Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.25;
Скачать: CL | DM;

Вниз

Обрезание текста в MEMO   Найти похожие ветки 

 
Ольга   (2005-07-04 13:45) [0]

Пишу текст в 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 раза меньше... Посоветуйте, где копать?


 
Digitman ©   (2005-07-04 14:19) [1]


> мой текст почти в 3 раза меньше


врешь.


 
TUser ©   (2005-07-04 14:21) [2]

До 100 000 строчек дошел - все рисует. Размер текста - 750Кб.

procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
 for i:=0 to MaxInt do begin
   Memo1.Lines.Add(inttostr(i));
   if i mod 117 = 0 then begin
     Label1.Caption:=inttostr(length(Memo1.Text));
     Application.ProcessMessages;
     end;
   end;
end;


 
Anatoly Podgoretsky ©   (2005-07-04 14:28) [3]

Ольга   (04.07.05 13:45)  
Что скажешь про операционную систему?


 
Ольга   (2005-07-04 15:10) [4]


> врешь.

Хотелось бы понять - где вру...

Программирую я под ХР, а у части пользователей Win98.
Цитирую из хелпа:
Note: Under Win 9x, there is a limit of 64k of text for this control.


 
Digitman ©   (2005-07-04 15:23) [5]


> Программирую я под ХР, а у части пользователей Win98


на них - на юзеров Маздая - и ориентируйся в дан.случае.

и не забывай, что юзер (маздайный или НТшный) смотреть на твою галиматью размером до и более 64к, в том виде в котором ты ему впрариваешь, не обязан - на то есть ПОЛНОЦЕННЫЕ текстовые редакторы !

а Memo (со своими маздайными 64к) хорош лишь для заведомо коротких файлов, а-ля ini ..


 
Ольга   (2005-07-04 15:34) [6]


> Memo (со своими маздайными 64к) хорош лишь для заведомо
> коротких файлов

Так я и пишу не более 25К. Может дело совсем не в МЕМО?

P.S.:  Digitman, фильтруй базар.


 
Digitman ©   (2005-07-04 15:37) [7]

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


 
TUser ©   (2005-07-04 15:37) [8]

> Может дело совсем не в МЕМО?

Точно - см. [2]!


 
Slym ©   (2005-07-04 15:41) [9]

Какаято несостыковка:
20000>size_text<25000 и 9000>count_lines<10000

count_lines*Length(#13#10) уже 18000-20000 байт!
т.е. у тебя полезного текста 0-5000 байт или всреднем 0.5 байта на строку?


 
Slym ©   (2005-07-04 15:43) [10]

А у тебя может так и получается 25000 байт полезного + 20000 байт бесполезных #13#10 + прочие накладные расходы...
вот и близок 64к


 
Ольга   (2005-07-04 15:49) [11]

Я ведь не сама символы считаю:
 size_text:=length(Memo1.Text);
Здесь, все переводы строк должны быть уже сосчитаны.


 
Slym ©   (2005-07-04 15:56) [12]

А если так:
count_lines:=Memo1.Lines.count;
size_text:=length(Memo1.Lines.Text);
помоему Memo1.Lines.Text и Memo1.Text разные весчи


 
Ольга   (2005-07-04 16:23) [13]

Проэкспериментировала:
size_text:=length(Memo1.Lines.Text) дает ~23000
for i:=0 to Memo1.Lines.Count-1 do   size_text:=size_text+length(Memo1.Lines[i]) дает ~21000, т.е. даже меньше.

Я уже пытаюсь искать ошибку не в МЕМО. Подробнее распишу конструкцию:
Некий цикл
Memo1.Lines.Add("кусок текста");
Конец цикла

Выглядит это так;
ADOQuery.Open;
While ADOQuery.not eof do
begin
  Memo1.Lines.Add("кусок текста");
  ADOQuery.Next;
end;
В стандартном режиме запрос выполняется быстро. Но, допустим, случилась какая-нибудь заморочка на сервере БД, и запрос отвалился по таймауту (это объясняет нестабильность ошибки). Тогда у меня вопрос: что прилетит клиенту с сервера (кроме сообщения об ошибке) - урезанная выборка данных или ничего? Я то рассчитываю на последнее. И как можно, не навредив,  сымитировать такую ситуацию, чтобы проверить мою гипотезу?


 
Digitman ©   (2005-07-04 17:07) [14]


> Memo1.Lines.Add("кусок текста");


как только ЭТО выполнилось БЕЗ исключений, считай что "кусок текста" 100%-но "добавился"

и все твои "выкорутасы" с БД к этому НЕ имеют НИ какого отношения.


 
ANB ©   (2005-07-04 17:16) [15]


> Ольга   (04.07.05 16:23) [13]
- тип БД ?


 
Ольга   (2005-07-04 17:22) [16]

Тип БД MSSQL

> Digitman ©  

ЭТО выполняется БЕЗ исключений. И тем ни менее текст выводится не весь. Возможно не все (изредка, по каким-то причинам) выбирается из БД.


 
ANB ©   (2005-07-04 17:28) [17]

Полный код приведи.


 
ANB ©   (2005-07-04 17:34) [18]

И, это, попробуй сначала в строку сложить, а потом уже ее в мемку кинуть. Заодно можешь вставить проверку на ошибку - переписалось из строки или нет. Если ошибка сохранится, а проверка покажет, что все нормально, значит проблема в чтении из БД.
Имхо, MSSQL + ADO + долгие запросы может не отработать.


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

Полный код слишком громоздкий. То что касается мемо я уже написала в [13]. Приведу еще строку формирования запроса, но думаю это ничего нового не добавит.
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";
     open;
     
     while not eof do
     begin
      Memo1.Lines.Add(FieldByName("h01").AsString);
      Next;
     end;

end;
 StatusBar1.Panels[1].Text:="строк="+inttostr(Memo1.Lines.count);
 StatusBar1.Panels[2].Text:="длина="+inttostr(length(Memo1.Text));
 Memo1.Visible:=True;


 
Ольга   (2005-07-04 17:46) [20]


> [18]

Так сейчас у меня все работает, как часы, хоть сначала в переменную, хоть сразу в мемо. А ждать, когда это повториться не хочется, тем более, что я работаю только днем, а пользователи круглые сутки.


 
Digitman ©   (2005-07-04 17:48) [21]

надеюсь, вся эта твоя байда у пользователя  творится в основном треде твоего процесса ...


 
ANB ©   (2005-07-04 17:50) [22]


> " 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 ? Какого типа ?


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

Хорошо, копирую весь код процедуры, как есть. Поля 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;


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

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


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

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


 
Ega23 ©   (2005-07-04 18:25) [26]

Query1:TADOQuery  ?


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

Да.


 
Alexander Panov ©   (2005-07-04 20:36) [28]

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

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


 
ANB ©   (2005-07-05 09:23) [29]


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


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

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


 
ANB ©   (2005-07-05 10:18) [31]


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


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

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


 
isasa ©   (2005-07-05 10:32) [33]

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

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

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


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


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

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


 
isasa ©   (2005-07-05 10:52) [35]

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

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

var buff: string;
.....

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


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

Добрый день!
Отвечаю всем, кто вникал в мои проблемы, пока я спала (плохо).
Напомню ситуацию: пользователь 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, а в вызывающей процедуре, как выяснилось, обработчик исключений в самом деле задавлен.
Т.е. выход такой - нормально обрабатываю исключения и жду следующего глюка? Который будет может через месяц, может через два... А как бы создать глючную ситуацию? Есть идеи?


 
ANB ©   (2005-07-05 17:35) [37]

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


 
имя   (2005-07-05 18:56) [38]

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


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


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

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


 
ANB ©   (2005-07-06 09:09) [40]

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



Страницы: 1 2 вся ветка

Текущий архив: 2005.07.25;
Скачать: CL | DM;

Наверх




Память: 0.6 MB
Время: 0.042 c
1-1120816924
agafon12
2005-07-08 14:02
2005.07.25
Проблема с картинкой и оле контейнером


14-1120253617
паша_голубь :-)
2005-07-02 01:33
2005.07.25
Благодарность


1-1120557755
Uran
2005-07-05 14:02
2005.07.25
Событие на bitmap в stringgrid


14-1119592535
Игорь Шевченко
2005-06-24 09:55
2005.07.25
Юрий Зотов, с днем рождения!


1-1120649855
maxim______m
2005-07-06 15:37
2005.07.25
string to string