![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обрезание текста в MEMO
Ольга © (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 ? Какого типа ?