Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.07.25;
Скачать: [xml.tar.bz2];

Вниз

Обрезание текста в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.013 c
1-1120466806
NightStranger
2005-07-04 12:46
2005.07.25
Как загрузить файл из интернета


4-1117194360
Masta Hookah
2005-05-27 15:46
2005.07.25
Replace Tray System Clock


14-1120200539
Priest
2005-07-01 10:48
2005.07.25
Запись последовательности действий на avi


14-1120073268
Profi
2005-06-29 23:27
2005.07.25
Как учтановить свой компонент в Delphi 2005?


1-1120939645
ronyn
2005-07-10 00:07
2005.07.25
Как менять цвет при XP Manifest?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский