powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DBGridEh - медленно создаются колонки
25 сообщений из 25, страница 1 из 1
DBGridEh - медленно создаются колонки
    #40013127
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача - отобразить график работ по дням. График составлен более чем на год вперед, т.е. колонок должно получиться около 400.
Если не создавать колонки, а просто прицепить сетку к MemTableEh, то процесс отображения происходит около 30 секунд, но колонки без заголовков. Нужны заголовки. Поэтому создаю колонки динамически, и в результате этого процесса время увеличивается примерно до 3 минут. Как ускорить?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
      if q.Open > 0 then
        begin
          i := 1;
          while not q.Q.Eof do
            begin
              AddNewField('m' + IntToStr(i), ftString);
              AddNewColumn('m' + IntToStr(i), q.GetDate('schedule_date'), 80);
              inc(i);
              q.Q.Next;
            end;
        end;



Где AddNewField - добавление столбца в MemTable,
AddNewColumn - создание и добавление колонки DBGridEh1.Columns в таблицу.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
  procedure AddNewField(AFieldName: string; AFieldType: TFieldType; AFieldSize: integer = 0); // добавляет поле в MemTableEh
  var
    fd: TFieldDef;
  begin
    fd := MemTableSchedule.FieldDefs.AddFieldDef;
    fd.DataType := AFieldType;
    fd.Name := AFieldName;
    if AFieldSize <> 0 then
      fd.Size := AFieldSize;
  end;

  procedure AddNewColumn(AFieldName: string; ADate: TDateTime; AWidth: integer); // добавляет колонки в сетку
  const
    FROM_BAND: integer = 5;
  var
    Column: TColumnEh;
    day: array[1..7] of string;
  begin
    day[1] := 'ПН';
    day[2] := 'ВТ';
    day[3] := 'СР';
    day[4] := 'ЧТ';
    day[5] := 'ПТ';
    day[6] := 'СБ';
    day[7] := 'ВС';

    Column := DBGridEh1.Columns.Add;
    Column.FieldName := AFieldName;
    Column.Title.Caption := DateToStr(ADate) + '|чел(чч)';
    Column.Width := AWidth;
    Column.Title.Alignment := taCenter;
    
    if IsHoliday(ADate) then
      Column.Tag := 1
    else
      Column.Tag := 0;    
  end;
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013136
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad,

у меня юзеры сотни по две полей в гриде создают, мгновенно создаются.
TVirtualStringTree.
Ну да ладно.
..

А заголовки не создаются сами, если к полям TMemTableEh добавить
Код: pascal
1.
  .DispayLabel := 'Итого|чел.час';


?
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013164
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
посмотрите там у грида в колонках что-то типа beginupdate и endupdate
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013171
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
29.10.2020 18:29, энди пишет:
> посмотрите там у грида в колонках что-то типа beginupdate и endupdate

не обязательно в колонках.
может быть у самого грида.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013265
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий

29.10.2020 18:29, энди пишет:
> посмотрите там у грида в колонках что-то типа beginupdate и endupdate

не обязательно в колонках.
может быть у самого грида.


MemTable.DisableControls / EnableControls?
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013266
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BeginLayout
EndLayout
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013272
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
svnvlad,

у меня юзеры сотни по две полей в гриде создают, мгновенно создаются.
TVirtualStringTree.
Ну да ладно.
..

А заголовки не создаются сами, если к полям TMemTableEh добавить
Код: pascal
1.
  .DispayLabel := 'Итого|чел.час';


?

Не создался. Выдает в тайтле имя поля, а не DisplayName.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013286
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Longneck
BeginLayout
EndLayout

Результат с BeginLayout - EndLayout самый быстрый - 49 сек.
С DisableControls - EnableControls - 85 сек.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013287
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
svnvlad,

у меня юзеры сотни по две полей в гриде создают, мгновенно создаются.
TVirtualStringTree.
Ну да ладно.

Вы динамически колонки создаете?
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013289
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Longneck
BeginLayout
EndLayout

Причем, сам цикл создания столбцов, если создавать только поля в MemTable, занимает 0 сек., если поля с колонками - 41 сек.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013316
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Без всяких BeginLayout и DisableControls. 187 милисекунд
ЧЯДНТ ?
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013319
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С BeginLayout немножечко быстрее
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013322
istrebitel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что возвращает q.Q? Непрерывный набор дат диапазона или с пропусками?
Если непрерывный, то я делаю так (у меня в MemTableEh часть полей создана уже в дизайне и в гриде колонки тоже).
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
TLGTAnalysisForm = class(TFrmMyChild_)
private
	{ Private declarations }
	FDateBegin, FDateEnd: TDateTime;
	FDynamicFields: TList<TFloatField>;
	FDynamicColumns: TList<TColumnEh>;
	FStartPeriodOffset: Integer;
end;

procedure TLGTAnalysisForm.FormCreate(Sender: TObject);
begin
  inherited;
  FDynamicFields := TList<TFloatField>.Create;
  FDynamicColumns := TList<TColumnEh>.Create;
end;

procedure TLGTAnalysisForm.RefreshQuery;
var
  DatePeriodAnalitFilter: IDatePeriodAnalitFilter;
begin
  //dbgMain.StartLoadingStatus();;
  dbgMain.BeginLayout;
  try
    mtMain.Close;	// <- MemTableEh отображаемый в гриде
    mtMain.DestroyTable;
    dbgMain.DataGrouping.Active := False;
    DeleteDynamicFields;
    DatePeriodAnalitFilter := (FFilters.FindFilter(cstDatePeriodAnalit, 0) as IDatePeriodAnalitFilter);
    FDateBegin := DatePeriodAnalitFilter.Value1; // Начало периода
    FDateEnd := DatePeriodAnalitFilter.Value2; // Конец периода
    CreateDynamicFields;
    TAnalitFiltersFireDACQueryBuilder.MakeFilter(FFilters, fdqMain);
    fdqMain.Open; // <- FDQuery содержащий данные которые надо разложить по колонкам
    mtMain.CreateDataSet;
    dbgMain.DataGrouping.Active := True;
  finally
    //dbgMain.FinishLoadingStatus();
    dbgMain.EndLayout;
  end;
end;

procedure TLGTAnalysisForm.DeleteDynamicFields;
var
  I: Integer;
begin
  for I := FDynamicColumns.Count - 1 downto 0 do
    FDynamicColumns[I].Free;
  FDynamicColumns.Clear;
  for I := FDynamicFields.Count - 1 downto 0 do
    FDynamicFields[I].Free;
  FDynamicFields.Clear;
end;

procedure TLGTAnalysisForm.CreateDynamicColumn(const Field: TField);
var
  ColumnEh: TColumnEh;
begin
  ColumnEh := dbgMain.Columns.Add;
  FDynamicColumns.Add(ColumnEh);
  ColumnEh.FieldName := Field.FieldName;
end;

procedure TLGTAnalysisForm.CreateDynamicFields;
var
  MonthsCount: Integer;
  FirstMonthBegin: Integer;
  Year, Month, Day: Word;
  I: Integer;
  FloatField: TFloatField;
  CurMonth: TDateTime;
  TitleCaption: string;
  FieldName: string;
begin
  FirstMonthBegin := Trunc(FDateBegin);
  DecodeDate(FDateBegin, Year, Month, Day);
  FStartPeriodOffset := Year * 12 + Month;
  DecodeDate(FDateEnd, Year, Month, Day);
  MonthsCount := Year * 12 + Month - FStartPeriodOffset + 1;
  SetLength(FSumQty, MonthsCount);
  CurMonth := FirstMonthBegin;
  for I := 0 to MonthsCount - 1 do
  begin
    TitleCaption := 'Потребность|' + IntToStr(YearOf(CurMonth)) + '|' + FormatSettings.LongMonthNames[MonthOf(CurMonth)];
    FieldName := 'DataField_' + Format('%.2d', [MonthOf(CurMonth)]) + '_' + IntToStr(YearOf(CurMonth));

    FloatField := TFloatField.Create(Self);
    FDynamicFields.Add(FloatField);
    FloatField.FieldName := FieldName;
    FloatField.DisplayLabel := TitleCaption;
    FloatField.DisplayFormat := cstFloatDisplayFormat;
    FloatField.DisplayWidth := cstFloatDisplayWidth;
    FloatField.DataSet := mtMain;
    CreateDynamicColumn(FloatField);

    CurMonth := IncMonth(CurMonth);
  end;

  FloatField := TFloatField.Create(Self);
  FDynamicFields.Add(FloatField);
  FloatField.FieldName := 'DataField_Total';
  FloatField.DisplayLabel := 'Потребность|Итого';
  FloatField.DisplayFormat := cstFloatDisplayFormat;
  FloatField.DisplayWidth := cstFloatDisplayWidth;
  FloatField.DataSet := mtMain;
  CreateDynamicColumn(FloatField);
  FTotalField := FloatField;
end;

function TLGTAnalysisForm.GetDynamicFieldIndex(const ADate: TDateTime): Integer;
var
  Year, Month, Day: Word;
begin
  DecodeDate(ADate, Year, Month, Day);
  Result := Year * 12 + Month - FStartPeriodOffset;
end;

procedure TLGTAnalysisForm.ddMainReadRecord(DataDriver: TDataDriverEh;
  MemTableData: TMemTableDataEh; MemRec: TMemoryRecordEh;
  var ProviderEOF: Boolean);
var
  CuratorId, LotId: Integer;
  DynFieldIdx: Integer;
  TotalOpened: Double;
  Opened: Double;
  Rec: TPrimaryKey;
  ReserveQty, StockQty, PurchaseQty, ClosedQty: Double;
  Keys: TArray<Integer>;

  procedure FillStaticFields1;
  begin
    MemRec.Value[mtMainmaterial_id.Index, dvvValueEh] := fdqMaindm_material_id.Value;
    MemRec.Value[mtMainmaterial_code.Index, dvvValueEh] := fdqMainmt_code.Value;
    MemRec.Value[mtMainmaterial_name.Index, dvvValueEh] := fdqMainmt_name.Value;
    MemRec.Value[mtMainunit_id.Index, dvvValueEh] := fdqMaindm_unit_id.Value;
    MemRec.Value[mtMainunit_abbr.Index, dvvValueEh] := fdqMainunt_abbr.Value;
  end;

  procedure CollectDemands;
  begin
    while not fdqMain.Eof and (Rec.MaterialId = fdqMaindm_material_id.Value) and (Rec.UnitId = fdqMaindm_unit_id.Value) do
    begin
      DynFieldIdx := GetDynamicFieldIndex(fdqMaindm_date.AsDateTime); // <- По дате вычисляем индекс
      FSumQty[DynFieldIdx] := FSumQty[DynFieldIdx] + fdqMaindm_qty.Value;
      ClosedQty := ClosedQty + fdqMaindm_factqty.Value;
      fdqMain.Next;
    end;
  end;
  
  procedure FillData1;
  var
    I: Integer;
  begin
    for I := 0 to High(FSumQty) do
    begin
      if (FSumQty[I] <> 0.0) then
        MemRec.Value[FDynamicFields[I].Index, dvvValueEh] := FSumQty[I]; // <- FDynamicFields[I] = TFoatField
      TotalOpened := TotalOpened + FSumQty[I];
    end;
    if (TotalOpened <> 0.0) then
      MemRec.Value[FTotalField.Index, dvvValueEh] := TotalOpened;
    if (ClosedQty <> 0.0) then
      MemRec.Value[FClosedField.Index, dvvValueEh] := ClosedQty;
    Opened := TotalOpened - ClosedQty;
    if Opened <> 0.0 then
      MemRec.Value[FOpenedField.Index, dvvValueEh] := Opened;
  end;

begin
  inherited;
  ProviderEOF := fdqMain.Eof;
  if ProviderEOF then
    Exit;
  if not fdqMain.Eof then
  begin
    FillStaticFields1;
    ResetSumAccumulators;
    Rec.MaterialId := fdqMaindm_material_id.Value;
    Rec.UnitId := fdqMaindm_unit_id.Value;
    CollectDemands;
    TotalOpened := 0.0;
    FillData1;
  end;
end;


Если даты с пропусками
Код: pascal
1.
2.
3.
4.
5.
6.
7.
// вместо
FDynamicFields: TList<TFloatField>;
FDynamicColumns: TList<TColumnEh>;
// сделать
FDynamicFields: TDictionary<Integer,TFloatField>;
FDynamicColumns: TDictionary<Integer,TColumnEh>;
//Key будет вычисляться просто округлением даты до Integer;


У меня данные заполняются в
Код: pascal
1.
2.
3.
procedure TLGTAnalysisForm.ddMainReadRecord(DataDriver: TDataDriverEh;
  MemTableData: TMemTableDataEh; MemRec: TMemoryRecordEh;
  var ProviderEOF: Boolean);


т.к. используется цепочка MemTableEh -> DataDriver -> FDQuery. Это самый быстрый способ заполнения.
Код: pascal
1.
2.
3.
MemTableEh.Append; 
Field.Value := Data; 
MemTableEh.Post;


значительно медленнее, но у меня 9000 строк, если у тебя строк мало можешь не заморачиваться.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013336
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
Без всяких BeginLayout и DisableControls. 187 милисекунд
ЧЯДНТ ?

Как что? Закомментировали функцию IsHoliday, которая обращается к базе и определяет, не помечена ли дата как выходной. :DDD
Это для раскраски колонок.
Закомментировал, стало 13 миллисекунд)
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013337
Tosh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad
DimaBr
Без всяких BeginLayout и DisableControls. 187 милисекунд
ЧЯДНТ ?

Как что? Закомментировали функцию IsHoliday, которая обращается к базе и определяет, не помечена ли дата как выходной. :DDD
Это для раскраски колонок.

Правильнее - вернуть список выходных за промежуток дат. Это позволит избавиться от затыка и уменьшит количество обращений к базе
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013338
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad
DimaBr
Без всяких BeginLayout и DisableControls. 187 милисекунд
ЧЯДНТ ?

Как что? Закомментировали функцию IsHoliday, которая обращается к базе и определяет, не помечена ли дата как выходной. :DDD
Это для раскраски колонок.
Закомментировал, стало 13 миллисекунд)

Этот признак может поменяться в любую секунду или в базе обычный рабочий календарь?
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013341
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman
svnvlad
пропущено...

Как что? Закомментировали функцию IsHoliday, которая обращается к базе и определяет, не помечена ли дата как выходной. :DDD
Это для раскраски колонок.
Закомментировал, стало 13 миллисекунд)

Этот признак может поменяться в любую секунду или в базе обычный рабочий календарь?

Может меняться, например задать выходной или переместить с воскресенья на понедельник.
Правильно будет так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
  procedure AddNewColumn(AFieldName: string; ADate: TDateTime; AIsHoliday: string; AWidth: integer); // добавляет колонки в сетку
  const
    FROM_BAND: integer = 5;
  var
    Column: TColumnEh;
  begin
    if DBGridEh1.FindFieldColumn(AFieldName) = nil then
      begin
        Column := DBGridEh1.Columns.Add;
        Column.FieldName := AFieldName;
        Column.Width := AWidth;
        Column.Title.Alignment := taCenter;
      end;
    Column.Title.Caption := DateToStr(ADate) + '|чел(чч)';

    if AIsHoliday = 'Y' then
      Column.Tag := 1
    else
      Column.Tag := 0;
  end;
....
...
...
...
         while not q.Q.Eof do
            begin
              AddNewField('m' + IntToStr(i), ftString);
              AddNewColumn('m' + IntToStr(i), q.GetDate('schedule_date'), q.GetVal('is_holiday'), 80);
              inc(i);
              q.Q.Next;
            end;
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013342
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad
Может меняться, например задать выходной или переместить с воскресенья на понедельник.

Не за те секунды же, пока строится таблица? Я к тому, что календарь один раз грузится, может даже кэшируется/хэшируется и доступ к нему за считанные мс, а не на каждый чих уточнять у сервера.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013352
istrebitel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С помощью глобальных свойств библиотеки можно настроить следующие возможности календаря.

- Подсвечивать праздники.
Для подсветки праздников и переноса рабочих дней используйте класс TWorkingTimeCalendarEh.

- Календарь поддерживать Delphi VCL стили.
Напишите наследник класса TWorkingTimeCalendarEh и переопределите метод IsWorkday

function IsWorkday(ADate: TDateTime): Boolean;
Метод должен возвращать True если переданная Дата является рабочим днем
В коде вашей программы один раз зарегистрируйте новый объект для работы с рабочим календарем с помощью глобальной процедуры RegisterGlobalWorkingTimeCalendar.

RegisterGlobalWorkingTimeCalendar( TMyWorkingTimeCalendarEh.Create(nil)).Free;
Данный метод регистрирует класс управления рабочими и выходными/праздничными днями, которые влияют на подсветку дней в компонентах выпадающего календаря и календаря выбора данных для планировщика событий – TPlannerCalendarPickerEh.
Метод возвращает старый объект управления днями. Обычно старой объект можно сразу удалять.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
 TMyWorkingTimeCalendarEh = class(TWorkingTimeCalendarEh)
  private
    fdqSpecDays :TFDQuery;
    fdqSpecDayswc_date :TSQLTimeStampField;
    fdqSpecDayswc_holiday :TBooleanField;
    fdqSpecDayswc_preholiday :TBooleanField;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function IsWorkday(ADate: TDateTime): Boolean; override;
    //procedure GetWorkingTime(ADate: TDateTime; var ATimeRanges: TTimeRangesEh); virtual;
  end;

constructor TMyWorkingTimeCalendarEh.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fdqSpecDays := TFDQuery.Create(Self);
  fdqSpecDays.Connection := dm3.fdcon;
  fdqSpecDays.Open('SELECT wc_date, wc_holiday, wc_preholiday FROM com_workcalendar');
  fdqSpecDayswc_date := (fdqSpecDays.Fields[0] as TSQLTimeStampField);
  fdqSpecDayswc_holiday := (fdqSpecDays.Fields[1] as TBooleanField);
  fdqSpecDayswc_preholiday := (fdqSpecDays.Fields[2] as TBooleanField);
  fdqSpecDays.IndexFieldNames := 'wc_date';
end;

destructor TMyWorkingTimeCalendarEh.Destroy;
begin
  fdqSpecDayswc_date := nil;
  fdqSpecDayswc_holiday := nil;
  fdqSpecDayswc_preholiday := nil;
  FreeAndNil(fdqSpecDays);
  inherited Destroy;
end;

function TMyWorkingTimeCalendarEh.IsWorkday(ADate: TDateTime): Boolean;
var
  WeekDay: TWeekDayEh;
begin
  ADate := Trunc(ADate);
  WeekDay := DateToWeekDayEh(ADate);
  Result := WeekDay in EhLibManager.WeekWorkingDays;
  if fdqSpecDays.Locate('wc_date', ADate, []) then
  begin
    Result := not fdqSpecDayswc_holiday.Value;
  end;
end;


RegisterGlobalWorkingTimeCalendar(TMyWorkingTimeCalendarEh.Create(nil)).Free;

...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013378
istrebitel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Потестил на 100000 вызовах IsWorkDay 800ms
Сделал рефакторинг.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
TMyWorkingTimeCalendarEh = class(TWorkingTimeCalendarEh)
  private
    FHolidays: TDictionary<Integer,Boolean>;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function IsWorkday(ADate: TDateTime): Boolean; override;
    procedure Refresh;
  end;

constructor TMyWorkingTimeCalendarEh.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FHolidays := TDictionary<Integer,Boolean>.Create;
  Refresh;
end;

destructor TMyWorkingTimeCalendarEh.Destroy;
begin
  FHolidays.Free;
  inherited Destroy;
end;

function TMyWorkingTimeCalendarEh.IsWorkday(ADate: TDateTime): Boolean;
var
  WeekDay: Word;
begin
  if FHolidays.TryGetValue(Trunc(ADate), Result) then
  begin
    Result := not Result;
  end else
  begin
    WeekDay := DayOfWeek(ADate);
    Result := (WeekDay > 1) and (WeekDay < 7);
  end;
end;

procedure TMyWorkingTimeCalendarEh.Refresh;
var
  fdqSpecDays :TFDQuery;
  fdqSpecDayswc_date :TSQLTimeStampField;
  fdqSpecDayswc_holiday :TBooleanField;
begin
  FHolidays.Clear;
  fdqSpecDays := TFDQuery.Create(Self);
  try
    fdqSpecDays.Connection := dm3.fdcon;
    fdqSpecDays.Open('SELECT wc_date, wc_holiday FROM com_workcalendar');
    fdqSpecDayswc_date := (fdqSpecDays.Fields[0] as TSQLTimeStampField);
    fdqSpecDayswc_holiday := (fdqSpecDays.Fields[1] as TBooleanField);
    while not fdqSpecDays.Eof do
    begin
      FHolidays.Add(Trunc(fdqSpecDayswc_date.AsDateTime), fdqSpecDayswc_holiday.Value);
      fdqSpecDays.Next;
    end;
    fdqSpecDays.Close;
  finally
    fdqSpecDays.Free;
  end;
end;



26ms
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013390
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svnvlad
ъъъъъ
svnvlad,

у меня юзеры сотни по две полей в гриде создают, мгновенно создаются.
TVirtualStringTree.
Ну да ладно.

Вы динамически колонки создаете?

Да.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013425
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman
svnvlad
Может меняться, например задать выходной или переместить с воскресенья на понедельник.

Не за те секунды же, пока строится таблица? Я к тому, что календарь один раз грузится, может даже кэшируется/хэшируется и доступ к нему за считанные мс, а не на каждый чих уточнять у сервера.

Решил же уже, постом выше. Просто сразу читаю даты, а с ними и выходной. В процедуру уже готовое значение передается.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40013609
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad

Как что? Закомментировали функцию IsHoliday, которая обращается к базе и определяет, не помечена ли дата как выходной. :DDD
Это для раскраски колонок.
Закомментировал, стало 13 миллисекунд)

То есть вы 400 раз спрашиваете у сервера выходной ли это день ?
Вместо того, что загрузить 10 выходных на клиент и гонять клиентский датасет.
И во всём грид конечно виноват !!!
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40014098
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr
svnvlad

Как что? Закомментировали функцию IsHoliday, которая обращается к базе и определяет, не помечена ли дата как выходной. :DDD
Это для раскраски колонок.
Закомментировал, стало 13 миллисекунд)

То есть вы 400 раз спрашиваете у сервера выходной ли это день ?
Вместо того, что загрузить 10 выходных на клиент и гонять клиентский датасет.
И во всём грид конечно виноват !!!

Ну я ж посмеялса уже над этой оплошностью.
...
Рейтинг: 0 / 0
DBGridEh - медленно создаются колонки
    #40014783
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не верю, что сразу нужны все 400.
Самое простое решение - их ограничить до разумного. Сделать постранично/помесячно.

Как вариант - поискать возможность ускорить поиск в БД для раскраски.
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DBGridEh - медленно создаются колонки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]