TStringGrid w Delphi 10.2.3 – upgrade 3 i błędne działanie kodu

0

Witam,
Mam dziwny problem po zrobieniu upgrade 3 program skompilowany spowolnił 100 krotnie. Nie chce mi się wierzyć ale puściłem starą wersję i wykonuje się w ciągu kilkadziesiąt sekund a ta nowa ponad 40 minuty.
To jakiś bug Embarcadero!
Co robi ta część programu? pętlą sobie chodzę po wierszach i komórkach TStringGrid i pobieram z nich wcześniej przetworzone dane - to proste rozwiązanie.
Jest tego sporo to ponad 50k ale jak wspomniałem dla starej wersji bez upgradu nie było problemu a teraz jest.
Jeszcze wspomne ze nie robiłem upgrade 2 tylko od razu 3 więc nie wiem jak byłoby dla 2.

for I := 2 to oForm1.Grid1.RowCount - 1 do
begin
 komponent:=oForm1.Grid1.Cells[0,i];
 klient:= oForm1.Grid1.Cells[5,i];

 // i po kolumnach...

Droga Redakcjo, co robić? jak żyć?

procedura działa tak, że pobiera z wierszy komponent,klient, a data i qty z kolumn /wewnętrzna pętla/ i następnie wykonuje procedure zapisu sp na ms sql dbo.R0387
to nie problem sp sql, zakomentowałem uruchomienie R0387.ExecProc i czas pracy omawianego fragmentu kodu sie prawie nie zmienił.
Wg mnie wydłużył się i to bardzo bardzo czas pobierania z Cells[x,y]
co o tym sądzicie? to działało przez wiele lat i po tym upgradzie problem!

Grid1.Visible:=false;
oForm1.visible:=false;
//
for I := 2 to oForm1.Grid1.RowCount - 1 do
begin
 komponent:=oForm1.Grid1.Cells[0,i];
 klient:= oForm1.Grid1.Cells[5,i];
 R0387.Parameters.ParamByName('@komponent').Value:=komponent;
 R0387.Parameters.ParamByName('@klient').Value:=klient;
 //
 plan:=0;
 wyciete:=0;
 //
 try
   plan:=StrToInt(StringReplace(oForm1.Grid1.Cells[9,i],'.','',[rfReplaceAll])); //plan
 except
 end;
 //
 try
   wyciete:=StrToInt(StringReplace(oForm1.Grid1.Cells[10,i],'.','',[rfReplaceAll])); //wyciete
 except
 end;
 //
 qdel:=0;
  try
   qdel:=StrToInt(StringReplace(oForm1.Grid1.Cells[6,i],'.','',[rfReplaceAll])); //qdel
 except
 end;
 //
 for j := 0 to 15+50 do //bylo 52
   begin
     data:= Days[j];
     try
     str:=StringReplace(oForm1.Grid1.Cells[11+j,i],'.','',[rfReplaceAll]);
     str:=StringReplace(str,'-','',[rfReplaceAll]);
     qty:=StrToInt(str); 
 
     except
      qty:=0;
     end;
 
 
    if (qty<>0) then
      begin
       week:=WeekOfTheYear(data);
       DecodeDate(data, dataYear, dataMonth, dataDay);
 
        R0387.Parameters.ParamByName('@data').Value:=DateToStr(data);
        R0387.Parameters.ParamByName('@zamowienie').Value:=qty;
        R0387.Parameters.ParamByName('@week').Value:=week;
        R0387.Parameters.ParamByName('@Produkcja').Value:=null;
        R0387.Parameters.ParamByName('@qdel').Value:=qdel;
    
       qdel:=0;
       if (Now+360>data)  then
        begin
          R0387.ExecProc;  
          kod:= R0387.Parameters.ParamByName('@RETURN_VALUE').value;
        end;
      end;
    //
   end;
 //
 end;
//
Caption:='R0387 zapisane do tablicy OrdersKomponenty!!!!';
//

0
pdusp napisał(a):

Nie chce mi się wierzyć ale puściłem starą wersję i wykonuje się w ciągu kilkadziesiąt sekund a ta nowa ponad 40 minuty.

Ale co się wykonuje 40 minut? Jaki kod? Ten który podałeś to za mało, aby cokolwiek określić.

To jakiś bug Embarcadero!

Wątpię.

Co robi ta część programu? pętlą sobie chodzę po wierszach i komórkach TStringGrid i pobieram z nich wcześniej przetworzone dane - to proste rozwiązanie.

No to po co się pytasz co ten kod robi, skoro wiesz dokładnie co robi?

Droga Redakcjo, co robić? jak żyć?

Nie wiemy jak wygląda dalsza część kodu i co faktycznie dzieje się w tej pętli. Dlatego też jedyne co mogę na ślepo doradzić to BeginUpdate przed pętlą i EndUpdate po niej. ;)

0

dziękuje za zainteresowanie, wyedytowałem i rozszerzyłem opis
Pozdrawia
Piotr

0

Czy jak tymczasowo zakomentujesz R0387.ExecProc; to też ten problem się pojawia?

0
szopenfx napisał(a):

Czy jak tymczasowo zakomentujesz R0387.ExecProc; to też ten problem się pojawia?

Tak od razu zrobiłem - wykluczyłem elementy bazodanowe.
Uruchamiam skompilowaną wersję sprzed upgrade 10.2.3 i wszystko działa momentalnie.
Jeszcze dodam że tych odczytów może być koło 50k więc może ktoś nie odczuje tego dla małego zbioru ale tu jest problem wyraźny...

Poprawiam swoją diagnozę, problem leży nie w TStringGrid a w obsłudze try except - to stało się stukrotnym spowalniaczem w 10.2.3!
przebudowałem tak pętle żeby wychwytywać niezgodne z Int i wróciłem do czasu wykonania poniżej 1 minuty.

 try
   plan:=StrToInt(StringReplace(oForm1.Grid1.Cells[9,i],'.','',[rfReplaceAll])); //plan
 except
 end;
 //
 try
   wyciete:=StrToInt(StringReplace(oForm1.Grid1.Cells[10,i],'.','',[rfReplaceAll])); //wyciete
 except
 end;
 //
 qdel:=0;
  try
   qdel:=StrToInt(StringReplace(oForm1.Grid1.Cells[6,i],'.','',[rfReplaceAll])); //qdel
 except
 end;
2

Ale zdajesz sobie sprawę z tego, że takie puste try except nie służą niczemu, a niepotrzebnie zamulają kod przez obsługę wyjątków? Obsługę, której i tak nie wykorzystujesz?

Te cztery bloki są z tyłka, co wynika z braku znajomości funkcji TryStrToInt, która wyjątków nie rzuca, a w zamian zwraca wartość logiczną informującą o tym, czy konwersja powiodła się, czy nie.


Edit: @kAzek przypomniał, że StrToIntDef zrobi dokładnie to czego oczekujesz, więc tej funkcji użyj.

Plan    := StrToIntDef(StringReplace(oForm1.Grid1.Cells[9,  i], '.', '', [rfReplaceAll]), 0);
Wyciete := StrToIntDef(StringReplace(oForm1.Grid1.Cells[10, i], '.', '', [rfReplaceAll]), 0);
QDel    := StrToIntDef(StringReplace(oForm1.Grid1.Cells[6,  i], '.', '', [rfReplaceAll]), 0);
0

zgoda!
StrToIntDef jest słuszniejszy niż try catch i nikt z tym nie polemizuje, w tym przypadku chciałem jednak pokazać że Delphi 10.2.3 kompilator inaczej reaguje /bo nie wspomnę o obsłudze błędu którego nawet nie ma/ niż wersja 10.2. Inaczej i gorzej bo czas wydłużył się 100-krotnie
Pozdrawia
Piotr

2
pdusp napisał(a):

Droga Redakcjo, co robić? jak żyć?

Może zacząć używać komponentów zgodnie z ich przeznaczeniem? ;) TStringGrid oraz inne kontrolki graficzne nie służą przechowywaniu danych. Osobiście to wpakowałbym dane do chociażby TClientDataSet i wyświetlił za pomocą TDBGrid. Wtedy byś przy pobieraniu danych nie miał tego problemu.

0

@Mr.YaHooo: i to jest prawidłowe rozwiązanie. TclientDataset bezproblemowo radzi sobie z tabelami zawierającymi nawet setki tysięcy rekordów, do tego posiada mechanizmy indeksowania, fitrowania, szukania

1 użytkowników online, w tym zalogowanych: 0, gości: 1