TDBGrid 및 cxGrid에서 sgcGrid로 마이그레이션

sgcGrid는 VCL 데이터 그리드 TsgcVCLGrid로, 모든 TDataSet에 바인딩되며 그룹화, 요약, 필터링, 찾기 패널, 밴드, 저장된 레이아웃을 모든 에디션에서 제공합니다. 이 키트는 사용 중인 TDBGrid 및 cxGrid 멤버를 sgcGrid의 대응 항목에 매핑하고, 컴파일된 데모의 코드를 보여 주며, 대응되지 않는 부분도 솔직하게 정리합니다.

두 가지 출발점, 하나의 그리드

기본 TDBGrid를 사용하는 Delphi VCL 팀, 그리고 구독을 재검토하는 DevExpress cxGrid 사용 팀입니다.

TDBGrid에서

기본 VCL TDBGrid는 데이터셋을 표시하고 편집할 뿐입니다. 필터 행, 열 필터, 그룹화, 푸터나 그룹 요약, 찾기 패널, 밴드, 최적 맞춤, 레이아웃 저장과 불러오기가 없습니다. 이 기능들은 모두 직접 코드를 작성하거나 서드파티 그리드를 써야 합니다. sgcGrid는 이 모든 기능을 하나의 컨트롤로 제공하며, 이미 사용 중인 데이터셋에 바인딩됩니다.

cxGrid에서

DevExpress cxGrid(ExpressQuantumGrid)는 폭넓고 성숙한 그리드입니다. 주로 그룹화, 요약, 필터링, 저장된 레이아웃을 갖춘 테이블 뷰로 사용하는 팀은 전체 소스 코드가 포함된 sgcGrid로 이 범위를 충분히 처리할 수 있으며, 그리드보다 훨씬 많은 범위를 포함하는 구독을 정리할 수 있습니다.

현재 그리드에 드는 비용: 2026-10-20 기준 DevExpress VCL 가격표에는 세 가지 구독이 있었고, 모두 ExpressQuantumGrid 컨트롤을 포함합니다. 가장 저렴한 것은 Express QuantumPack으로 USD 999.99이며, VCL Subscription은 USD 1,699.99입니다. 2025년 9월 18일의 Delphi-PRAXiS 스레드에서 한 사용자는 cxGrid 구독 가격이 USD 400에서 USD 550로 올랐다고 보고했고, 다른 회원은 새로운 Express GridPack 라이선스를 더 이상 판매하지 않는다는 DevExpress 공지를 인용했습니다(활성 구독자는 계속 갱신할 수 있습니다). sgcGrid는 €199부터 개발자 단위로 라이선스되며 전체 소스 코드와 1년간의 업데이트가 포함되고, 모든 sgcUI 에디션에도 포함되어 있습니다.

하나의 컨트롤, 모든 TDataSet에 바인딩

TsgcVCLGrid와 TsgcGridSource_DataSet에 DataSet, Grid, KeyField를 지정합니다. 데이터셋 이벤트가 그리드를 동기화 상태로 유지합니다.

모든 에디션

FieldName로 매칭되는 디자인된 열, 조회 필드, 셀, 행, 다중 행 선택, 행 헤더, 사용자 정의 그리기, Ctrl+C, 그룹 패널, 푸터 및 그룹 요약, 필터 행, Excel 스타일 열 필터, 찾기 패널, 밴드, 최적 맞춤, JSON 레이아웃 저장 및 불러오기.

Registered 에디션 전용

데이터셋으로의 양방향 편집(WriteBack), 커서 동기화(SyncCursor), 삽입, 삭제, 붙여넣기, 실행 취소, 카드 뷰(ViewStyle), 매우 큰 테이블을 위한 서버 모드. 체험판에는 평가를 위해 포함되어 있습니다. Community 빌드에는 포함되지 않으며, 데모는 그곳에서도 컴파일되지만 그리드를 읽기 전용으로 표시합니다.

TDBGrid 멤버와 sgcGrid 대응 항목

아래의 모든 sgcGrid 이름은 배포되는 소스에 있으며, 데모에서 사용하는 이름은 그 안에서 컴파일됩니다.

TDBGrid sgcGrid 에디션
TDBGridTsgcVCLGrid(유닛 sgcGrid_VCL)전체
DataSourceTsgcGridSource_DataSet: DataSet, Grid, KeyField, 그다음 Active := True(유닛 sgcGrid_Source_DataSet)전체
Columns, TColumn.FieldNameColumns, Columns[i].FieldName. 디자인된 열은 유지되고 FieldName으로 매칭되며, 열이 없으면 AutoColumns가 열을 만듭니다전체
Title.Caption, Width, VisibleColumns[i].Caption, Width, Visible전체
TColumn.ReadOnlyColumns[i].Editable전체(편집: Registered)
TColumn.PickList, 조회 필드 드롭다운Columns[i].PickList. 조회 필드의 경우 소스가 LookupDataSet에서 목록을 채웁니다전체(값 쓰기: Registered)
TField.DisplayFormatColumns[i].DisplayFormat전체
ReadOnly, Options dgEditingTsgcVCLGrid.ReadOnly(기본값 True) 및 TsgcGridSource_DataSet.WriteBackRegistered
dgRowSelectSelectionMode := gsmRow(gsmCell 미사용 시)전체
dgMultiSelect, SelectedRowsSelectionMode := gsmMultiRow; SelectedRows, SelectedRowCount, GetSelectedKeys, RowSelected[]전체
dgIndicatorRowHeader := [grhIndicator](grhNumbers, grhCheckBox도 있음)전체
dgColLines, dgRowLinesGridLinesV, GridLinesH전체
현재 레코드가 그리드를 따라감TsgcGridSource_DataSet.SyncCursorRegistered
OnDrawColumnCell, DefaultDrawColumnCellaDefaultDraw를 사용하는 OnCustomDrawCell. 색상만 바꾸려면 OnGetCellStyle 또는 FormatRules전체
OnTitleClickOnHeaderClick전체
Ctrl+C(사용자 코드)기본 제공(Ctrl+C, Ctrl+Ins). 텍스트는 SelectionToText에서 가져옵니다전체
Insert 및 Ctrl+Del 키AllowInsert, AllowDelete, InsertRow, DeleteSelectedRows, OnBeforeDeleteRegistered

cxGrid 멤버와 sgcGrid 대응 항목

cxGrid 이름은 DevExpress 식별자이며 참고용으로만 제시합니다.

cxGrid sgcGrid 에디션
TcxGridDBTableView, DataController.DataSourceTsgcVCLGrid 및 TsgcGridSource_DataSet전체
TcxGridDBColumn.DataBinding.FieldNameColumns[i].FieldName전체
TcxGridDBColumn.GroupIndexColumns[i].GroupIndex; GroupBy(['Field']), ClearGrouping, GroupCount전체
OptionsView.GroupByBoxShowGroupPanel전체
DataController.Groups.FullExpand, FullCollapseExpandAll, CollapseAll전체
OptionsView.FooterShowFooter전체
DataController.Summary.FooterSummaryItems(skSum, skCount, skAverage, skMin, skMax)Columns[i].SummaryType(gsuSum, gsuCount, gsuAverage, gsuMin, gsuMax), SummaryFormat. 값은 FooterSummary(aCol), FooterSummaryText(aCol)에서 가져오며 SummaryScope도 있습니다전체
DataController.Summary.DefaultGroupSummaryItemsGroupSummaries. 그룹에서 열의 SummaryType을 사용합니다전체
FilterRow.VisibleShowFilterRow, Columns[i].FilterRowOperator전체
열 필터 드롭다운ShowFilterButtons, ShowFilterPopup(aCol), ClearColumnFilter(aCol), ClearColumnFilters, OnFilterChange전체
FindPanel.DisplayModeShowFindPanel, FindText, FindNext, FindPrevious, FindOnlyMatches전체
TcxGridDBBandedTableView.Bands, Column.Position.BandIndexBands (Caption, ParentBand, Visible), Columns[i].Band전체
ApplyBestFitBestFitColumns, BestFitColumn(aCol), BestFitOnDblClick, BestFitSampleRows전체
StoreToIniFile, RestoreFromIniFileSaveLayoutToFile, LoadLayoutFromFile(JSON). 문자열이나 스트림과의 상호 변환도 가능하며, AutoSaveLayout 및 LayoutStorageKey로 자동화됩니다전체
OptionsCustomize.ColumnMovingColumnMoving전체
열 사용자 지정 대화 상자ShowColumnChooser전체
OnCustomDrawCellOnCustomDrawCell전체
TcxGridDBCardView(두 번째 뷰)같은 그리드에서 ViewStyle := gvsCard, CardOptions(CaptionField, CardWidth, CardHeight, ShowFieldCaptions)Registered

컴파일된 데모의 코드

각 발췌 코드는 Delphi 7과 Delphi 13(Win32 및 Win64)에서 컴파일되는 MigrateFromDBGrid 데모에서 복사한 것입니다. 주석에는 대체하는 TDBGrid 또는 cxGrid 코드가 표시되어 있습니다.

바인딩: DataSource가 TsgcGridSource_DataSet으로 바뀝니다

변경 전: TDBGrid와 DataSource := dsProducts. 변경 후: 폼의 소스 컴포넌트.

frmMain.dfm
object SourceDB: TsgcGridSource_DataSet
  DataSet = cdsProducts
  Grid = GridDB
  KeyField = 'ID'
  Left = 280
  Top = 520
end

TDBGrid 옵션이 속성으로 바뀝니다

변경 전: dgEditing, dgRowSelect, dgMultiSelect, dgIndicator가 있는 Options. 변경 후:

frmMain.pas
procedure TFormMain.chkOptionsClick(Sender: TObject);
begin
  // TDBGrid.ReadOnly / Options dgEditing -> ReadOnly
{$IFDEF SGC_GRID_EDIT}
  GridDB.ReadOnly := not chkEditing.Checked;
{$ENDIF}
  // dgMultiSelect -> gsmMultiRow, dgRowSelect -> gsmRow, neither -> gsmCell
  if chkMultiSelect.Checked then
    GridDB.SelectionMode := gsmMultiRow
  else if chkRowSelect.Checked then
    GridDB.SelectionMode := gsmRow
  else
    GridDB.SelectionMode := gsmCell;
  // dgIndicator -> RowHeader [grhIndicator] (grhNumbers, grhCheckBox too)
  if chkIndicator.Checked then
    GridDB.RowHeader := [grhIndicator]
  else
    GridDB.RowHeader := [];
end;

OnDrawColumnCell이 OnCustomDrawCell로 바뀝니다

변경 전: Column.FieldName과 필드 값을 읽는 OnDrawColumnCell. 변경 후: aCol는 Columns 인덱스이고 aRow는 Data의 뷰 행입니다(CS_LOW_STOCK는 데모의 상수입니다).

frmMain.pas
procedure TFormMain.GridDBCustomDrawCell(Sender: TObject; aCanvas: TsgcUICanvas;
  aRow, aCol, aLeft, aTop, aRight, aBottom: Integer;
  aState: TsgcGridCellDrawStates; var aDefaultDraw: Boolean);
begin
  // TDBGrid.OnDrawColumnCell: Column.FieldName and Field.AsInteger.
  // sgcGrid: aCol is the Columns index, aRow the view row of Data. The
  // background is painted already; aDefaultDraw False would skip the text
  if (aRow < 0) or (aRow >= GridDB.Data.ViewCount) or
    (GridDB.Columns[aCol].FieldName <> 'Qty') then
    Exit;
  if StrToIntDef(VarToStr(GridDB.Data.Cells[aRow, aCol]), 0) < CS_LOW_STOCK
  then
  begin
    // a red marker at the left edge of a low stock cell
    aCanvas.BeginPath;
    aCanvas.Rectangle(aLeft, aTop + 4, aLeft + 4, aBottom - 4);
    aCanvas.ClosePath;
    aCanvas.FillPath($FFDC2626);
  end;
end;

쓰기 반영, 커서 동기화, 그룹화

변경 전: TDBGrid의 dgEditing, 그리고 cxGrid GroupByBox로 끌어다 놓은 열. 변경 후:

frmMain.pas
procedure TFormMain.FormCreate(Sender: TObject);
begin
  DoCreateData;
  // TDBGrid: DataSource := dsProducts. sgcGrid: a TsgcGridSource_DataSet
  // with DataSet, Grid and KeyField (set on the form). The grid columns are
  // designed on the form like TDBGrid.Columns, matched by FieldName
{$IFDEF SGC_GRID_EDIT}
  // TDBGrid dgEditing posts edits to the dataset: WriteBack. The current
  // record follows the focused row and back: SyncCursor
  SourceDB.WriteBack := True;
  SourceDB.SyncCursor := True;
{$ELSE}
  chkEditing.Checked := False;
  chkEditing.Enabled := False;
  chkEditing.Caption := 'Editing (Registered edition)';
  GridDB.ReadOnly := True;
{$ENDIF}
  SourceDB.Active := True;
  SourceCx.Active := True;
  chkOptionsClick(nil);
  // cxGrid: drag a column to the GroupByBox. sgcGrid: ShowGroupPanel, and
  // GroupBy from code (cxGridDBColumn.GroupIndex is Columns[i].GroupIndex)
  GridCx.GroupBy(['Category']);

디자인 타임의 cxGrid 테이블 뷰 기능

변경 전: 푸터 요약 항목, 그룹 기준 상자, 필터 행, 찾기 패널, 밴드형 테이블 뷰. 변경 후: 폼의 열 속성과 그리드 속성.

frmMain.dfm
Columns = <
  item
    FieldName = 'ID'
    Caption = 'ID'
    DataType = gdtInteger
    Width = 60
    SummaryType = gsuCount
    Band = 0
  end
  item
    FieldName = 'Product'
    Caption = 'Product'
    Width = 220
    Band = 0
  end
  item
    FieldName = 'Category'
    Caption = 'Category'
    Width = 140
    Band = 0
  end
  item
    FieldName = 'Price'
    Caption = 'Price'
    DataType = gdtFloat
    Width = 110
    DisplayFormat = '#,##0.00'
    SummaryType = gsuAverage
    SummaryFormat = '#,##0.00'
    Band = 1
  end
  item
    FieldName = 'Qty'
    Caption = 'Qty'
    DataType = gdtInteger
    Width = 90
    SummaryType = gsuSum
    Band = 1
  end>
FormatRules = <>
ShowFooter = True
ShowGroupPanel = True
GroupSummaries = True
ShowFilterButtons = True
ShowFilterRow = True
ShowFindPanel = True
Bands = <
  item
    Caption = 'Product'
  end
  item
    Caption = 'Stock and price'
  end>

최적 맞춤, 레이아웃, 카드 뷰

변경 전: ApplyBestFit, StoreToIniFile, RestoreFromIniFile, TcxGridDBCardView. 변경 후:

frmMain.pas
procedure TFormMain.btnBestFitClick(Sender: TObject);
begin
  // cxGridDBTableView.ApplyBestFit -> BestFitColumns (BestFitColumn(i) for
  // one column, BestFitOnDblClick for the header divider)
  GridCx.BestFitColumns;
end;

function TFormMain.DoLayoutFile: string;
begin
  Result := ExtractFilePath(ParamStr(0)) + 'migratefromdbgrid_layout.json';
end;

procedure TFormMain.btnSaveLayoutClick(Sender: TObject);
begin
  // cxGridDBTableView.StoreToIniFile -> SaveLayoutToFile (JSON: columns,
  // widths, order, sort, grouping, filters, summaries, bands, view)
  GridCx.SaveLayoutToFile(DoLayoutFile);
  DoShowStatus('layout saved to ' + ExtractFileName(DoLayoutFile));
end;

procedure TFormMain.btnLoadLayoutClick(Sender: TObject);
begin
  // cxGridDBTableView.RestoreFromIniFile -> LoadLayoutFromFile
  if GridCx.LoadLayoutFromFile(DoLayoutFile) then
    DoShowStatus('layout loaded')
  else
    DoShowStatus('no saved layout');
end;

procedure TFormMain.chkCardViewClick(Sender: TObject);
begin
{$IFDEF SGC_GRID_ADVANCED}
  // cxGridDBCardView (a second view of the level) -> ViewStyle gvsCard of
  // the same grid, CardOptions for the caption field and the card size
  if chkCardView.Checked then
    GridCx.ViewStyle := gvsCard
  else
    GridCx.ViewStyle := gvsTable;
{$ENDIF}
end;

폼당 일곱 단계

데이터 계층은 그대로 둡니다. 그리드와 그 옵션만 바뀝니다.

1

컴포넌트 배치

sgcGrid 패키지를 설치한 다음 폼에 TsgcVCLGrid와 TsgcGridSource_DataSet를 배치합니다.

2

데이터셋 지정

소스의 DataSet를 이전 그리드가 사용하던 데이터셋으로 설정하고(그리드는 더 이상 TDataSource가 필요 없습니다), 이어서 Grid와, 제자리 업데이트와 쓰기 반영에 필요한 고유 필드인 KeyField를 설정합니다.

3

열 다시 만들기

FieldName, Caption, Width, DisplayFormat, Editable가 있는 Columns를 추가하거나, Columns를 비워 두고 AutoColumns가 필드에서 열을 만들게 합니다.

4

옵션 매핑

dgEditing는 ReadOnly와 WriteBack로, dgRowSelect와 dgMultiSelect는 SelectionMode로, dgIndicator은 RowHeader로, 현재 레코드는 SyncCursor로 대응합니다.

5

그리기 코드 이동

OnDrawColumnCell 코드를 OnCustomDrawCell로 옮기거나, 색상만 설정하는 경우 OnGetCellStyle로 옮깁니다.

6

cxGrid 기능 켜기

ShowGroupPanel, ShowFooter, GroupSummaries, ShowFilterRow, ShowFilterButtons, ShowFindPanel. 요약은 Columns[i].SummaryType, 밴드는 Bands 및 Columns[i].Band, 레이아웃은 SaveLayoutToFile로 옮깁니다.

7

활성화

데이터셋이 열리면 소스에서 Active := True를 설정합니다.

일대일로 대응되지 않는 부분

이동을 계획하기 전에 먼저 읽어 보세요.

MigrateFromDBGrid

40개 제품이 담긴 하나의 TClientDataSet과 Category 조회 필드를 "TDBGrid에서"와 "cxGrid에서" 두 페이지에 표시합니다.

위치

sgcUI 설치 프로그램이 Demos\Grid\Delphi\MigrateFromDBGrid에 설치합니다. MigrateFromDBGrid.dpr, frmMain.pas, frmMain.dfm, readme.html가 들어 있습니다.

실행 방법

Delphi 7~13 중 아무 버전에서나 MigrateFromDBGrid.dpr를 열고 Win32 또는 Win64로 빌드한 다음 실행하세요. 각 페이지에는 TDBGrid 또는 cxGrid 개념이 sgcGrid 대응 항목 옆에 표시됩니다.

자체 테스트

MigrateFromDBGrid.exe /test는 열 및 옵션 매핑, 복사 텍스트, 그룹화, 푸터 요약, 밴드, 레이아웃 왕복, 그리고 Registered 에디션에서는 쓰기 반영과 카드 뷰를 확인하고, 모든 검사를 통과하면 0으로 종료합니다.

두 그리드를 공정하게 말씀드리면, cxGrid에는 sgcGrid에 없는 기능이 있습니다. 하나의 그리드 컨트롤에서 여러 뷰와 레벨을 사용하는 것, INI 레이아웃, 그리고 다른 대규모 컨트롤 모음이 그것입니다. 애플리케이션이 이런 기능에 의존한다면 이동 작업은 이 페이지에 나온 것보다 커집니다. 위에 나열한 그리드 기능을 사용하고 있고, 전체 소스 코드와 함께 Delphi 7~13에서 단일 제품으로 쓰고 싶다면 sgcGrid가 알맞은 선택입니다. 전체 기능 목록은 sgcGrid 제품 페이지를 참조하세요.

최고의 가성비: All-Access모든 eSeGeCe 제품과 프리미엄 지원이 포함되어 연 €1,059부터 이용할 수 있어요.
All-Access 가격 보기

오늘 첫 그리드를 옮겨 보세요

sgcGrid와 MigrateFromDBGrid 데모가 포함된 sgcUI 체험판을 다운로드하고 첫 번째 폼을 옮겨 보세요.