Форум: "Основная";
Текущий архив: 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]Есть мысля по поводу глюков - я наблюдал иногда эффект, если в мемку маленькими кусочками добавлять текст, то иногда ее глючит и она перестает ПОКАЗЫВАТЬ часть текста. На самом деле внутри все лежит, но не видно. Помогает несколько раз свернуть/развернуть окно. Выборка из базы уже у тебя отделена от вывода. Теперь отдели подготовку вывода от самого присвоения текста мемки (т.е. сначала в строку). И работать быстрее будет.
← →
Ольга (2005-07-06 10:54) [41]Спасибо, так и сделала. Буду ждать следующего глюка (хотелось бы не дождаться).
А эксперимент с кабелем на практике выполнить сложно, запрос выполняется доли секунды - фиг попадешь.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.07.25;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.016 c