Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обрезание текста в MEMO


Страницы:   1 2 3

Ольга ©   (2005-07-04 13:45:00) 

Пишу текст в MEMO стандартными методами:
Memo1.Clear;
Некий цикл
 Memo1.Lines.Add('кусок текста');
Конец цикла
count_lines:=Memo1.Lines.count;
size_text:=length(Memo1.Text);

Периодически, когда 20000>size_text<25000 и 9000>count_lines<10000 (все это приблизительно), последние строки в MEMO не рисуются.
Воспроизвести ситуацию, чтобы понять причину, не могу, т.к. возникает она редко и сама по себе рассасывается, несколько потрепав нервы пользователю.
Не могу понять в чем дело, ограничение у MEMO.Text 64 Kб, мой текст почти в 3 раза меньше... Посоветуйте, где копать?


Ольга   (2005-07-06 10:54:00) [1]

Спасибо, так и сделала. Буду ждать следующего глюка (хотелось бы не дождаться).
А эксперимент с кабелем на практике выполнить сложно, запрос выполняется доли секунды - фиг попадешь.


ANB   (2005-07-06 09:09:00) [2]

Есть мысля по поводу глюков - я наблюдал иногда эффект, если в мемку маленькими кусочками добавлять текст, то иногда ее глючит и она перестает ПОКАЗЫВАТЬ часть текста. На самом деле внутри все лежит, но не видно. Помогает несколько раз свернуть/развернуть окно. Выборка из базы уже у тебя отделена от вывода. Теперь отдели подготовку вывода от самого присвоения текста мемки (т.е. сначала в строку). И работать быстрее будет.


Ольга   (2005-07-05 19:42:00) [3]


> Выдерни сетевой кабель

Круто! Смешно, но мысль интересная, попробую...


  (2005-07-05 18:56:00) [4]

Удалено модератором


ANB   (2005-07-05 17:35:00) [5]

Выдерни сетевой кабель :))) Кстати, я так и в самом деле раз тестировал.


Ольга   (2005-07-05 13:08:00) [6]

Добрый день!
Отвечаю всем, кто вникал в мои проблемы, пока я спала (плохо).
Напомню ситуацию: пользователь 99 раз выполнял программу и все было ОК. На 100-ый раз - данные сформировались не полностью, хотя они в БД есть и он их видит (на графике). С полчаса чертыханий, перезапусков программы и ... все ОК.
Что за это время изменилось?
1. ехе-шник прежний (значит алгоритм расчета значений правильный),
2. МЕМО тот же (значит его памяти хватает),
3. данные в БД корректные (там жесткие проверки при записи, символьных полей нет, только datetime,int,float), и за полчаса с ними ничего не происходит.
Все стабильно, кроме работы сервера БД и локальной сети.

Я немного ввела народ в заблуждение. Блок try except:
try
  open;
except
  on E:Exception do ShowMessage('Ошибка при выполнении запроса из таблицы '+ TName+'. Обратитесь к разработчику. Текст ошибки: '+E.ClassName+'. '+E.Message);
end;
я сделала только вчера (забыла выкинуть), раньше был голый open, а в вызывающей процедуре, как выяснилось, обработчик исключений в самом деле задавлен.
Т.е. выход такой - нормально обрабатываю исключения и жду следующего глюка? Который будет может через месяц, может через два... А как бы создать глючную ситуацию? Есть идеи?


isasa   (2005-07-05 10:52:00) [7]

Если
Memo1.Visible:=true
то процесс заполнения отслеживается на экране(а пользователь не шалеет:) )

Memo1.Lines.Add "долго" добавляет строку,
я бы исправил

var buff: string;
.....

buff:=buff+<строка>;
...
и в конце
Memo1.Lines.Text:=buff;
Memo1.Update;


Faraday   (2005-07-05 10:42:00) [8]


> ANB ©   (05.07.05 10:18) [31]

Бывают глюки с НД именно когда перед циклом не стоит first, особенно если к Query1 подвязаны какие-нибудь компоненты (grid или DBLookupComboBox).


isasa   (2005-07-05 10:32:00) [9]

Что вернет сервер клиенту в ответ на запрос, прервавшийся по таймауту?

Зависит от свойства TADOConnection
CursorLocation:=clUseClient
по умолчанию
по Open - весь набор 'select ...' на клиенте

Какой смысл обрабатывать набор при тайм ауте
try
      open;
    except
       on E:Exception do ShowMessage('Ошибка при выполнении запроса из таблицы '+
            TName+'. Обратитесь к разработчику. Текст ошибки: '+E.ClassName+'. '+E.Message);
exit;
    end;


ANB   (2005-07-05 10:25:00) [10]

Судя по коду, мемка заполняется не в цикле по дейтасету, а в цикле по массиву значений. => Чтение с сервера не причем и его данный тоже. У тебя обработчик исключений часом не задавлен ? Компиляешь с включенной проверкой Range и прочими флагами ? Так как индексы массива ты рассчитываешь динамически, возможно ошибка там. Все имхо.


ANB   (2005-07-05 10:18:00) [11]


> Faraday   (05.07.05 09:41) [30]
- open вроде как сам позиционирует на первую запись


Faraday   (2005-07-05 09:41:00) [12]

Перед while not eof do поставь first.
Или в процедуре Getdph происходит позиционнирование курсора на нужной записи?


ANB   (2005-07-05 09:23:00) [13]


> Ольга   (04.07.05 18:21) [25]
- ошибку он вернет. Заметили бы. Исключения ты, вроде, не перехватываешь.


Alexander Panov   (2005-07-04 20:36:00) [14]

Ольга   (04.07.05 18:28) [27]

Протестируй данные, которые в БД, на наличие неоторажаемых символов, например на значение #0.


Ольга   (2005-07-04 18:28:00) [15]

Да.


Ega23   (2005-07-04 18:25:00) [16]

Query1:TADOQuery  ?


Ольга   (2005-07-04 18:21:00) [17]

Это точно. Я бы хотела вернуться к обсуждению [13]. Что вернет сервер клиенту в ответ на запрос, прервавшийся по таймауту?


Ega23   (2005-07-04 18:11:00) [18]

Кошмар какой....


Ольга   (2005-07-04 17:57:00) [19]

Хорошо, копирую весь код процедуры, как есть. Поля h01-h48 типа float.

 procedure PrepareMaket(Typ: Integer; TName: string; npp, nm: Integer);
 var i, j, k : Integer;    
 begin
   TextMemoTXT:='';
   //чистим массивы
   for i:=0 to ListKod.Count-1 do
   with TData(ListKod.Objects[i]) do
   begin
     for j:=0 to 47 do FValues[j]:=-32768;
     YVal:=-32768; TVal:=-32768;
   end;

   //заполняем массивы
   with Query1 do
   begin
     sql.Text:='select * from '+TName+' where '+
     ' nplan is not null AND (';
     for i:=0 to listNum.count-1 do
       if i=0
         then sql.Text:=sql.Text+' nplan='+listNum[i]
         else sql.Text:=sql.Text+' or nplan='+listNum[i];
     sql.Text:=sql.Text+') and type='+inttostr(Typ);

     sql.text:=sql.text+' and (data BETWEEN :data1 AND :data2)';
     t:=DateLast12355-1;
     parameters.ParamValues['data1']:=t;
     t:=DateLast12355+1;
     parameters.ParamValues['data2']:=t;

     sql.Text:=sql.Text+' order by nplan, data';
     try
       open;
     except
        on E:Exception do ShowMessage('Ошибка при выполнении запроса из таблицы '+
             TName+'. Обратитесь к разработчику. Текст ошибки: '+E.ClassName+'. '+E.Message);
     end;

     //при выборе данных берем смещение с учетом того, что данные в
     //DG_ph и dg_h начинаются с 1.00 Московского времени (3.00 - уральского)
     dph:=Getdph;

     while not eof do
     begin
       i:=listNum.IndexOf(FieldByName('nplan').asString);
       if i<>-1 then
       with TData(ListKod.Objects[i]) do
       begin
         j:=round(FieldByName('data').AsDateTime-DateLast12355);

         if npp=48 then
         begin
           case j of
             -1:
               begin
                 j2:=48;
                 if dph<0 then j1:=49+dph else j1:=49;
               end;
             1:
               begin
                 j1:=1;
                 if dph>0 then j2:=dph else j2:=0;
               end;
             else
               begin
                 j1:=1; j2:=48;
                 if dph<0 then j2:=48+dph;
                 if dph>0 then j1:=1+dph;
               end;
           end;

           for j:=j1 to j2 do
             values[(j+48-dph-1) mod 48]:=FieldByName('h'+FormatFloat('00',j)).AsFloat;
         end
         else  //npp=24
         begin
           dph24:=floor((dph+1)/2);

           case j of
             -1:
               begin
                 j2:=24;
                 if dph24<0 then j1:=24+dph24  else j1:=25;
                 if (dph24<=0) then//Надо взять еще одно значение, чтобы определить первую полусумму, если смещение не кратно целому часу
                 begin
                   YVal:=FieldByName('h'+FormatFloat('00', j1-1)).AsFloat;
                 end;
               end;
             1:
               begin
                 j1:=1;
                 if dph24>0 then j2:=dph24 else j2:=0;
                 if (dph24>=0) then//Надо взять еще одно значение, чтобы определить последнюю полусумму, если смещение не кратно целому часу
                 begin
                   TVal:=FieldByName('h'+FormatFloat('00',j2+1)).AsFloat;
                 end;
               end;
             else
               begin
                 j1:=1; j2:=24;
                 if dph24<0 then j2:=24+dph24;
                 if dph24>0 then j1:=1+dph24;
                 if (dph24>0) then//Надо взять еще одно значение, чтобы определить первую полусумму, если смещение не кратно целому часу
                 begin
                   YVal:=FieldByName('h'+FormatFloat('00',j1-1)).AsFloat;
                 end;
                 if (dph24<0) then //Надо взять еще одно значение, чтобы определить последнюю полусумму, если смещение не кратно целому часу
                 begin
                   TVal:=FieldByName('h'+FormatFloat('00',j2+1)).AsFloat;
                 end;
               end;
           end;

           for j:=j1 to j2 do
           begin
             values[(j*2+48-dph-2) mod 48]:=FieldByName('h'+FormatFloat('00',j)).AsFloat;

             //заполняем полусуммы
             if ((j*2+48-dph-2) mod 48 > 1) AND
               (values[((j*2+48-dph-2) mod 48)-2]<>-32768) AND
               (values[(j*2+48-dph-2) mod 48]<>-32768) then
                 values[((j*2+48-dph-2) mod 48)-1]:=
                   (values[((j*2+48-dph-2) mod 48)-2]+values[(j*2+48-dph-2) mod 48])/2;
           end;
         end;

       end;
       next;
     end;
     close;
   end;

   //формируем макет

   if (nm=12355) or (nm=13355) then
      with TDateTime_DateTime(DateLast12355) do
      Memo1.Lines.Add('//'+IntToStr(nm)
        +':'+nstr0(day,2)+nstr0(month,2)+Copy(IntToStr(year),3,2)+':'+
        trim(TAdres(SpisokAdres.Selected.data).kod)+':'+nstr0(SE_korr.Value,2)+':++')
   else
     with TDateTime_DateTime(DateLast12355) do
     Memo1.Lines.Add('//'+IntToStr(nm)
     +':'+nstr0(month,2)+nstr0(day,2)+':'+
     trim(TAdres(SpisokAdres.Selected.data).kod)+':'+nstr0(SE_korr.Value,2)+':++');
   // xml
   if xml_frm then
      CreateXML('d:\aaa\test.xml',trim(TAdres(SpisokAdres.Selected.data).kod),'00:00');

   for i:=0 to ListKod.count-1 do
   with TData(ListKod.Objects[i]) do
   begin
     if npp=24 then //Определим 0 и 47 значения массива, если они пустые.
     begin
       if (YVal<>-32768) AND (Values[1]<>-32768) AND (Values[0]=-32768) then
         Values[0]:=(YVal+Values[1])/2;
       if (TVal<>-32768) AND (Values[46]<>-32768) AND (Values[47]=-32768) then
         Values[47]:=(TVal+Values[46])/2;
     end;
     for k:=0 to 47 do valforxml[k]:=-32768;
     
     Memo1.Lines.Add('('+Kod+'):');
     sum:=0;
     for k:=0 to n div 8-1 do
     begin
       st:='';
       for j:=0 to 7 do
       begin
         if n=48 then
         begin
           v:=values[k*8+j];
           valforxml[k*8+j]:=v;
         end  
         else
         begin
           //Если знач передаются с xx.30, то берем нечетные элементы, иначе - четные
           v:=values[((k*8+j)*2) + (ServisSend12355.SpinEdit3.Value div 30)];
           valforxml[((k*8+j)*2) + (ServisSend12355.SpinEdit3.Value div 30)]:=v;
         end;

         if v=-32768 then
         begin
             st:=st+':';
             sum:=-32768;
         end
         else
         begin
             st:=st+floattostr(arfround(v,0))+':';
             if sum<>-32768 then sum:=sum+v;
         end;
       end;
       Memo1.Lines.add(st);
     end;
     if xml_frm then WriteGrafToXML(kod, valforxml);
     if sum=-32768 then st:=':'
     else
       if n=24 then st:=FloatToStr(arfround(sum,0))+':'
       else st:=FloatToStr(arfround(sum/2,0))+':';
     Memo1.Lines.add(st);
   end;
   Memo1.Lines.Add('==');
 end;


ANB   (2005-07-04 17:50:00) [20]


> ' nplan is not null AND (';
>      for i:=0 to listNum.count-1 do
>        if i=0
>          then sql.Text:=sql.Text+' nplan='+listNum[i]
>          else sql.Text:=sql.Text+' or nplan='+listNum[i];
>      sql.Text:=sql.Text+') and type='+inttostr(Typ);
- вообще то через IN будет немного короче, хотя на логику это влиять не должно.


> inttostr(length(Memo1.Text))
- уже писали, замени на Memo1.Lines.Text

Приведи полный код цикла заполнения.
Что есть h01 ? Какого типа ?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо