📄 jvdbultimgrid.pas
字号:
// Checking of OnUserSort assignment
if Assigned(OnUserSort) then
SortWith := swUserFunc;
if (SortWith = swUserFunc) and not Assigned(OnUserSort) then
raise EJVCLDbGridException.CreateRes(@RsEJvDBGridUserSortNotAssigned);
// Checking of index properties
if (SortWith = swIndex) and
not (IsPublishedProp(DSet, cIndexDefs) and IsPublishedProp(DSet, cIndexName)) then
raise EJVCLDbGridException.CreateRes(@RsEJvDBGridIndexPropertyMissing)
else
if (SortWith = swFields) and
not IsPublishedProp(DSet, cIndexFieldNames) then
raise EJVCLDbGridException.CreateRes(@RsEJvDBGridIndexPropertyMissing);
// Sorting
Screen.Cursor := crHourGlass;
DSet.DisableControls;
try
SortString := '';
DescString := '';
MaxFTS := Length(FieldsToSort) - 1;
for FTS := 0 to MaxFTS do
begin
FieldsToSort[FTS].Name := Trim(FieldsToSort[FTS].Name);
SortField := DSet.FieldByName(FieldsToSort[FTS].Name);
if (SortField is TBlobField) or (SortField is TBytesField) or
((SortField.FieldKind <> fkData) and (SortField.FieldKind <> fkInternalCalc)) then
begin
// No sorting of binary or special fields
if BeepOnError then
begin
SysUtils.Beep;
continue;
end
else
raise EJVCLDbGridException.CreateRes(@RsEJvDBGridBadFieldKind);
end
else
if SortWith = swIndex then
begin
// Sort with index
if SortString <> '' then
SortString := SortString + ';';
SortString := SortString + FieldsToSort[FTS].Name;
if FieldsToSort[FTS].Order = JvGridSort_DESC then
begin
if DescString <> '' then
DescString := DescString + ';';
DescString := DescString + FieldsToSort[FTS].Name;
end;
if FTS = MaxFTS then
begin
SearchIndex;
if not SortOK then
begin
if Assigned(OnIndexNotFound) then
begin
Retry := False;
OnIndexNotFound(Self, FieldsToSort, SortString, DescString, Retry);
if Retry then
begin
SearchIndex;
if not SortOK then
raise EJVCLDbGridException.CreateRes(@RsEJvDBGridIndexMissing);
end;
end
else
raise EJVCLDbGridException.CreateRes(@RsEJvDBGridIndexMissing);
end;
end;
end
else
if (SortWith = swFields) or (SortWith = swUserFunc) then
begin
// Sort with fields (temporary index) or user function
if SortString <> '' then
SortString := SortString + ',';
SortString := SortString + '[' + FieldsToSort[FTS].Name + ']';
if FieldsToSort[FTS].Order = JvGridSort_ASC then
SortString := SortString + ' ASC'
else
SortString := SortString + ' DESC';
if FTS = MaxFTS then
begin
if SortWith = swUserFunc then
begin
OnUserSort(Self, FieldsToSort, SortString, FSortOK);
if SortOK then
FSortedFields := FieldsToSort;
end
else
UpdateProp(cIndexFieldNames, SortString);
end;
end;
end;
finally
DSet.EnableControls;
Screen.Cursor := crDefault;
end;
end;
end;
procedure TJvDBUltimGrid.SetMultiColSort(const Value: Boolean);
begin
if FMultiColSort <> Value then
begin
FMultiColSort := Value;
if Assigned(FSortedFields) and not FMultiColSort then
begin
SetLength(FSortedFields, 1);
Sort(FSortedFields);
end;
end;
end;
procedure TJvDBUltimGrid.DoTitleClick(ACol: Longint; AField: TField);
var
Keys: TKeyboardState;
Found, ShiftOrCtrlKeyPressed: Boolean;
SortArraySize: Integer;
FieldsToSort: TSortFields;
I: Integer;
begin
FSortOK := False;
try
if Assigned(AField) then
begin
Found := False;
SortArraySize := 1;
if Assigned(FSortedFields) then
begin
ShiftOrCtrlKeyPressed := MultiColSort and GetKeyboardState(Keys);
if ShiftOrCtrlKeyPressed then
ShiftOrCtrlKeyPressed :=
(((Keys[VK_SHIFT] and $80) <> 0) or ((Keys[VK_CONTROL] and $80) <> 0));
SetLength(FieldsToSort, Length(FSortedFields));
for I := 0 to Length(FSortedFields) - 1 do
begin
FieldsToSort[I].Name := FSortedFields[I].Name;
if AnsiSameText(AField.FieldName, FSortedFields[I].Name) then
begin
Found := True;
if not ShiftOrCtrlKeyPressed then
begin
SetLength(FieldsToSort, 1);
FieldsToSort[0].Name := AField.FieldName;
FieldsToSort[0].Order := not FSortedFields[I].Order;
Break;
end
else
FieldsToSort[I].Order := not FSortedFields[I].Order;
end
else
FieldsToSort[I].Order := FSortedFields[I].Order;
end;
if (not Found) and ShiftOrCtrlKeyPressed then
SortArraySize := Length(FSortedFields) + 1;
end;
if not Found then
begin
SetLength(FieldsToSort, SortArraySize);
FieldsToSort[SortArraySize - 1].Name := AField.FieldName;
FieldsToSort[SortArraySize - 1].Order := JvGridSort_ASC;
end;
Sort(FieldsToSort);
end;
finally
if Assigned(OnTitleBtnClick) then
OnTitleBtnClick(Self, ACol, AField);
end;
end;
procedure TJvDBUltimGrid.SaveGridPosition;
begin
FSavedBookmark := DataLink.DataSet.Bookmark;
FSavedRowPos := DataLink.ActiveRecord;
end;
procedure TJvDBUltimGrid.RestoreGridPosition;
begin
if Assigned(FOnRestoreGridPosition) then
begin
// This example for ADO datasets positions the dataset cursor exactly
// where it was before it moves (put this code into your event):
//
// Delphi code:
// if (MyADODataSet.BookmarkValid(SavedBookmark)) then
// MyADODataSet.Recordset.Bookmark := POleVariant(SavedBookmark)^;
// try MyADODataSet.Resync([rmExact]); except end;
//
// BCB code:
// if (MyADODataSet->BookmarkValid(SavedBookmark))
// MyADODataSet->Recordset->Bookmark = *(POleVariant)SavedBookmark;
// try {MyADODataSet->Resync(TResyncMode() << rmExact);} catch (...) {}
//
DataLink.ActiveRecord := FSavedRowPos;
FOnRestoreGridPosition(Self, Pointer(FSavedBookmark), FSavedRowPos);
end
else
if DataLink.DataSet.BookmarkValid(Pointer(FSavedBookmark)) then
DataLink.DataSet.GotoBookmark(Pointer(FSavedBookmark));
end;
function TJvDBUltimGrid.PrivateSearch(var ResultCol: Integer; var ResultField: TField;
const CaseSensitive, WholeFieldOnly, Next: Boolean): Boolean;
var
DSet: TDataSet;
Start, ColNo, I: Integer;
Found: Boolean;
FieldText: string;
begin
Result := False;
if Assigned(DataLink) and DataLink.Active then
begin
Screen.Cursor := crHourGlass;
DSet := DataSource.DataSet;
DSet.DisableControls;
try
// Start location
SaveGridPosition;
if Next then
begin
Start := Col;
if not (dgIndicator in Options) then
Inc(Start);
end
else
begin
Start := 0;
DSet.First;
end;
// The search begins...
while not DSet.Eof do
begin
for ColNo := Start to Columns.Count - 1 do
for I := 0 to SearchFields.Count - 1 do
begin
if AnsiSameText(SearchFields[I], Columns[ColNo].FieldName) then
with Columns[ColNo].Field do
begin
if Assigned(OnGetText) then
FieldText := DisplayText
else
FieldText := AsString;
if FieldText <> '' then
begin
// Search inside the field content
if CaseSensitive then
begin
if WholeFieldOnly then
Found := AnsiSameStr(string(FValueToSearch), FieldText)
else
Found := (StrSearch(string(FValueToSearch), FieldText) > 0);
end
else
begin
if WholeFieldOnly then
Found := AnsiSameText(string(FValueToSearch), FieldText)
else
Found := (StrFind(string(FValueToSearch), FieldText) > 0);
end;
// Text found ! -> exit
if Found then
begin
ResultCol := ColNo;
if dgIndicator in Options then
Inc(ResultCol);
ResultField := Columns[ColNo].Field;
Result := True;
Exit;
end;
end;
end;
end;
Start := 0;
DSet.Next;
end;
finally
DSet.EnableControls;
Screen.Cursor := crDefault;
end;
end;
end;
function TJvDBUltimGrid.Search(const ValueToSearch: Variant; var ResultCol: Integer;
var ResultField: TField; const CaseSensitive, WholeFieldOnly, Focus: Boolean): Boolean;
begin
Result := False;
if (SearchFields.Count > 0) and (ValueToSearch <> Null) and (ValueToSearch <> '') then
begin
FValueToSearch := ValueToSearch;
Result := PrivateSearch(ResultCol, ResultField, CaseSensitive, WholeFieldOnly, False);
if Result and Focus then
begin
Self.Col := ResultCol;
if Self.Visible then
Self.SetFocus;
end
else
RestoreGridPosition;
end;
end;
function TJvDBUltimGrid.SearchNext(var ResultCol: Integer; var ResultField: TField;
const CaseSensitive, WholeFieldOnly, Focus: Boolean): Boolean;
begin
Result := False;
if (SearchFields.Count > 0) and (FValueToSearch <> Null) and (FValueToSearch <> '') then
begin
Result := PrivateSearch(ResultCol, ResultField, CaseSensitive, WholeFieldOnly, True);
if Result and Focus then
begin
Self.Col := ResultCol;
if Self.Visible then
Self.SetFocus;
end
else
RestoreGridPosition;
end;
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -