Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 6

Автор: landy
Дата сообщения: 29.12.2014 08:20
Зависит от механизмов этого разбора. Обычно это XXstring или TStream, дальше уже можно перенести данные в TStringList.
Автор: topdon
Дата сообщения: 29.12.2014 12:56
Механизм разбора- выделение фиксированной подстроки с определенной позиции,
в этой подстроке- нахождение подстрок по разделителям внутри.

Добавлено:
Спасибо. Я прошу дать ссылку, если можно, или привести элем. пример.
У меня в поле doc
ADOQuery1.SQL := 'select id, doc from Book';
сидит строка более 5000 символов. В БД формат ntext
Если бы я мог написать типа

Var
s: string;
...
s := adoquery1.fieldbyname('doc').asstring;

то был бы вполне удовлетворен.
А с потоками никогда не работал.




Автор: SuPriTo
Дата сообщения: 29.12.2014 13:35
topdon

Цитата:
s := adoquery1.fieldbyname('doc').asstring;

У вас данный код не работает, что ли?
Тут только вопрос с памятью может возникнуть, если символов окажется слишком много.
5000 символов - это очень мало.
Автор: landy
Дата сообщения: 29.12.2014 14:44
topdon ты же вроде уже раньше решил эту проблему с доступом к полю DOC через CAST? Или такое решение не работает?
Автор: topdon
Дата сообщения: 29.12.2014 15:47
Да, все работает вроде. Не помню, что меня смутило.
Ошибка в другом, прошу прощения.
Автор: Ichigo2
Дата сообщения: 27.01.2015 19:48
Привет.
У меня на StringGrid стоит OnMouseMove и подсвечивается ячейка под курсором, получается такой более-менее "живой" грид. Но при попытке Drag'n'Drop'а на таблицу она замирает. Можно ли сделать одновременно драгндроп и рабочий МаусМув, чтобы визуально отображать ячейку для дропанья?
У таблицы DragKind=dkKind, DragMode=dmManual
Автор: ShIvADeSt
Дата сообщения: 28.01.2015 09:25
Ichigo2
Обрабатывай OnDragOver, в нем делай все что необходимо.
Автор: DmitryKz
Дата сообщения: 06.02.2015 14:10
Ребята, подскажите, какая последняя версия Indy 10 нормально билдится в проекте Delphi 2006? Крайняя из снапшота (равно и тибурон) при билдинге проекта ругаются с ошибкой компилятора Internal Error.
Автор: landy
Дата сообщения: 19.02.2015 21:28
DmitryKz, тут написано, что 10.1.5. Думаю, надо попробовать тщательно вычистить все следы перед установкой и перебирать релизы.
Автор: DmitryKz
Дата сообщения: 19.02.2015 21:42
landy
10.1.5 это "родная", идущая в дистрибутиве. Попробую перебрать релизы..
Автор: landy
Дата сообщения: 20.02.2015 07:14
DmitryKz, а на каком хоть модуле оно падает?
Автор: DmitryKz
Дата сообщения: 20.02.2015 16:38
landy


Цитата:
[Pascal Fatal Error] IdGlobal.pas(8657): F2084 Internal Error: C4955


Начинаю тест релизов - на трёх крайних падает..
Автор: DmitryKz
Дата сообщения: 20.02.2015 19:26
Последний непадающий с Tubro Delphi релиз - 5239. В IdGlobal.pas релиза 5260 по-иному именованы типы данных для некоторых переменных в функции function ReadLnFromStream (строка 8564). Вероятно, на этом компилятор и падает.
Автор: sammozg
Дата сообщения: 27.08.2015 07:33
Доброго времени суток!
Прошу помощи в решении непонятной мне проблемы, пишу программу на Delphi 7 для сохранения технических данных в БД Access, всё работает, но с течением времени размер программы в taskmgr потихоньку увеличивается, при запуске программа весит 5МБ, после подключения к БД 10МБ, за каждые сутки прибавляет минимум по 30 МБ, делал через компоненты ADO(Connect, Command, пытался и на Query) уничтожение компонентов никакой пользы не приносит и заставить их не увеличивать свой размер тоже не получается. Приведу полный код процедур создания, удаления и записи
[more]
procedure ServerArhStart; ////ADOCommand ðàáî÷èé
var
Time : TDateTime;
Year, Month, Day, Hour, Min, Sec, MSec: Word;
PfileNameOpen, PFileNameSave: PChar;
FileNameOpen, FileNameSave, adocon: String;
i,j,k,s: integer;
begin
s:=0;
For j:=1 to StrToInt(KRSet.KolGroup) do begin
For i:=1 to StrToInt(KRSet.MasGroup[j].KRkol) do begin
For k:=1 to StrToInt(KRSet.MasGroup[j].KR[i].INRKol) do begin
s:=s+1;
SetLength(ArhSet,s);
ArhSet[s-1].Group:=j;
ArhSet[s-1].KR:=i;
ArhSet[s-1].InrOkr:=k;
end;
if StrToInt(KRSet.MasGroup[j].KR[i].OKRKol)>0 then begin
s:=s+1;
SetLength(ArhSet,s);
ArhSet[s-1].Group:=j;
ArhSet[s-1].KR:=i;
ArhSet[s-1].InrOkr:=0;
end;
end;
end;
SetLength(ADOConBD,s);
SetLength(ADOComADD,s);
Time := Now();
DecodeDate(Time, Year, Month, Day);
Month1:=Month;
For i:=0 to Length(ArhSet)-1 do begin
ADOConBD[i]:=TADOConnection.Create(nil);
ADOComADD[i]:=TADOCommand.Create(nil);
ADOComADD[i].CommandTimeout:=1;
if ArhSet[i].InrOkr=0 then begin
FileNameOpen:='./Lib\KRBDBASESOKR.mdb';
FileNameSave:='./Bases\KRBDBASES_G'+IntToStr(ArhSet[i].Group)+'_K'+IntToStr(ArhSet[i].KR)+'_OKR_G'+IntToStr(Year)+'_M'+IntToStr(Month)+'.mdb';
if not FileExists(FileNameSave) then begin
PfileNameOpen:=PChar(FileNameOpen);
PFileNameSave:=PChar(FileNameSave);
CopyFile(PfileNameOpen, PFileNameSave, False);
end;
ADOConBD[i].Connected:=False;
adocon:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+ FileNameSave+';Persist Security Info=False';
ADOConBD[i].ConnectionString:=adocon;
ADOComADD[i].Connection:=ADOConBD[i];
ADOConBD[i].Connected:=True;
end else begin
FileNameOpen:='./Lib\KRBDBASESINR.mdb';
FileNameSave:='./Bases\KRBDBASES_G'+IntToStr(ArhSet[i].Group)+'_K'+IntToStr(ArhSet[i].KR)+'_INR'+IntToStr(ArhSet[i].InrOkr)+'_G'+IntToStr(Year)+'_M'+IntToStr(Month)+'.mdb';
if not FileExists(FileNameSave) then begin
PfileNameOpen:=PChar(FileNameOpen);
PFileNameSave:=PChar(FileNameSave);
CopyFile(PfileNameOpen, PFileNameSave, False);
end;
ADOConBD[i].Connected:=False;
adocon:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+ FileNameSave+';Persist Security Info=False';
ADOConBD[i].ConnectionString:=adocon;
ADOComADD[i].Connection:=ADOConBD[i];
ADOConBD[i].Connected:=True;
end;
end;
end;

procedure ServerArhStop;
var
i,J1, J2: integer;
P1, P2: Pointer;
begin

For i:=0 to Length(ArhSet)-1 do begin
ADOConBD[i].Connected:=False;
//ADOComADD[i].Destroying;
//P1:= @ADOConBD[i];
//J1:= Sizeof(ADOConBD[i]);
//P2:= @ADOComADD[i];
//J2:= Sizeof(ADOComADD[i]);
//FreeMem(P);
//ADOComADD[i].CleanupInstance;
//ADOComADD[i].Active:=False;
FreeAndNil(ADOComADD[i]);
FreeAndNil(ADOConBD[i]);
//FreeMem(P1);
//FreeMem(P2);
//ADOConBD[i].Free;
//ADOComADD[i].Free;
//ADOComADD[i].Destroy;
//ADOConBD[i].Destroy;
end;


// FreeAndNil(ADOComADD);
// FreeAndNil(ADOConBD);


SetLength(ADOConBD,0);
ADOConBD:=nil;
SetLength(ADOComADD,0);
ADOComADD:=nil;
SetLength(ArhSet,0);
end;


procedure ServerArhWork;
var
Time : TDateTime;
Year, Month, Day: Word;
i, j, k,n: integer;
Dannie:Array [0..125] of Single;
PointDannie: ^Single;
OKRByte:Array [0..21] of Byte;
FileName1, FileName2, SQLADD, VARStr: String;
begin
Time := Now();
DecodeDate(Time, Year, Month, Day);
if Month<>Month1 then begin
ServerArhStop;
ServerArhStart;
end;
For i:=0 to Length(ArhSet)-1 do begin
if ArhSet[i].InrOkr=0 then begin
For k:=1 to StrToInt(KRSet.MasGroup[ArhSet[i].Group].KR[ArhSet[i].KR].OKRKol) do begin
SQLADD:= 'INSERT INTO OKR'+IntToStr(k)+' ([DataTime]';
For j:=1 to 22 do SQLADD:= SQLADD+', B'+IntToStr(j);
SQLADD:= SQLADD+') VALUES (:Time';
For n:=0 to 21 do begin
OKRByte[n]:=KRGroupData[ArhSet[i].Group].KRDATA[ArhSet[i].KR].OKR[23*(k-1)+n+1];
SQLADD:=SQLADD+ ', '+IntToStr(OKRByte[n]);
end;
SQLADD:=SQLADD+');';
ADOComADD[i].CommandText:=SQLADD;
ADOComADD[i].Parameters.ParamByName('Time').DataType:= ftDateTime;
ADOComADD[i].Parameters.ParamByName('Time').Value:=Time;
ADOComADD[i].ExecuteOptions:=[eoExecuteNoRecords];
ADOComADD[i].Execute;
end;
end else begin
SQLADD:= 'INSERT INTO DATA ([Datetime]'; // ) VALUES ('''', CAST('+VARStr+')'; //'''+VARStr+'''
for j:=1 to StrToInt(KRSet.MasGroup[ArhSet[i].Group].KR[ArhSet[i].KR].INR[ArhSet[i].InrOKR]) do SQLADD:= SQLADD+', INR'+IntToStr(j);
SQLADD:= SQLADD+') VALUES (:Time';
For n:=0 to StrToInt(KRSet.MasGroup[ArhSet[i].Group].KR[ArhSet[i].KR].INR[ArhSet[i].InrOKR])-1 do begin
PointDannie:=@KRGroupData[ArhSet[i].Group].KRDATA[ArhSet[i].KR].INR[ArhSet[i].InrOKR-1].INRIO[4*n];
Dannie[n]:=PointDannie^;
SQLADD:=SQLADD+ ', '+StringReplace(FloatToStrF(Dannie[n], ffExponent, 8, 4), ',', '.', [rfReplaceAll, rfIgnoreCase]); //FloatToStr(Dannie[n]); //Dannie['+inttostr(n)+'])'
end;
SQLADD:=SQLADD+');';
ADOComADD[i].CommandText:=SQLADD; //SYSDATETIME()
ADOComADD[i].Parameters.ParamByName('Time').DataType:= ftDateTime;
ADOComADD[i].Parameters.ParamByName('Time').Value:=Time;
ADOComADD[i].ExecuteOptions:=[eoExecuteNoRecords];
ADOComADD[i].Execute;
end;
end;
end;
[/more]
Прошу помогите устранить причину увеличения размера, или хотя бы как размер обратно вернуть к 5МБ
Автор: idiMAN
Дата сообщения: 27.08.2015 08:20
sammozg
Это Вам для начала...
Блог GunSmoker-а Ищем утечки памяти
Использование AutomatedQA MemProof
Delphi отображение утечки памяти
Автор: sammozg
Дата сообщения: 27.08.2015 10:13
idiMAN
Про утечки памяти я уже кучу чего перечитал, пробовал отслеживать момент уничтожения объекта, знаю что утечка в ADO компонентах(где то натыкался на описание подобного типа СОМ объект хранится в памяти после уничтожения) методы free, destroy, freeandnil эффекта не дали... после них освобождается пара сотен КБ, а остальное весит, но и при запуске увеличивается на те же пару сотен...
Автор: idiMAN
Дата сообщения: 27.08.2015 11:05
Я предложил просто найти, где именно происходит утечка. Если вы твёрдо уверены, что утечка внутри системы, а не в самих ADO-компонентах, то боюсь ничего не поделать, иначе нужно править исходники ADO-компонентов.
Автор: sammozg
Дата сообщения: 27.08.2015 12:28
Я засовывал их в отдельный поток, видно что поток уничтожается а вот память не освобождается, может есть вариант принудительно освободить память?
Автор: SuPriTo
Дата сообщения: 27.08.2015 12:33
sammozg

Цитата:
Я засовывал их в отдельный поток, видно что поток уничтожается а вот память не освобождается, может есть вариант принудительно освободить память?

Значит поток не уничтожает память. Иначе бы память освободилась.
Автор: idiMAN
Дата сообщения: 27.08.2015 12:48
sammozg
Насколько я знаю, память принадлежит процессу, а не потоку. Так что уничтожение потока не приведёт к освобождению выделенной в нём памяти, тем более если она "утекла".
Автор: Frodo_Torbins
Дата сообщения: 27.08.2015 13:08

Цитата:
при запуске программа весит 5МБ, после подключения к БД 10МБ
Это нормально.
Цитата:
за каждые сутки прибавляет минимум по 30 МБ
А какой максимум? Если оно останавливается гдето на 200 Мб, то все ОК и нет повода беспокоится. А если может дойти до 1,5 Гб, и продолжить расти, то это конечно проблема.
Но это не обязательно утечка, тут еще может быть проблема в фрагментации памяти. Делфийский менеджер памяти (в последних версиях) неплохо с этим справляется, а вот что там в СОМ, сильно зависит от версии винды.

P.S. И сюда еще загляните: https://support.microsoft.com/ru-ru/kb/978155
Автор: sammozg
Дата сообщения: 27.08.2015 14:57

Цитата:
А какой максимум?

Максимум пока не определил, так-как работаю с тестовыми данными, но предположительно раза в 4 больше, но если оно больше 200-300 мб расти не будет этого бы хватило, но оно же не останавливается, а программа должна непрерывно работать,

Цитата:
P.S. И сюда еще загляните: https://support.microsoft.com/ru-ru/kb/978155

Спасибо за информацию, я тестировал на WinXP, попробую на ночь оставить на Win7x64, посмотрю может всё-таки в винде дело...

Автор: sammozg
Дата сообщения: 03.09.2015 09:44
По тестировал на разных ОС эффекта нет, залез в TADO дошел до ole32.dll, на этом ступор, и у меня созрел вполне логичный вопрос, можно ли её как нибудь выгрузить принудительно, так как в конструкторе:
constructor TADOCommand.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCommandObject := CreateADOObject(CLASS_Command) as _Command;
FParameters := TParameters.Create(Self, TParameter);
FParamCheck := True;
CommandType := cmdText;
CommandTextAlias := 'CommandText'; { Do not localize }
ComponentRef := Self;
end;

Self - означает что компонент самостоятельный....
Автор: ant0ni02004
Дата сообщения: 03.09.2015 10:38
при использовании ADO проблема в том, что строки (строковые значения полей) остаются в кеше. вот они память и сжирают постепенно.
Автор: sammozg
Дата сообщения: 03.09.2015 10:58
ant0ni02004
Если я правильно понимаю то под DLL выделяется две памяти, в одной хранится сама DLL в другой данные которые использует, но вот как очистить эту область с данными я пока не нашел, поэтому и пытаюсь удалить из памяти всю DLL, а так как она вызывается не через loadLibrery, а как external, то не получается её выгрузить стандартным FreeLibrery. Может знаешь как кэш почистить?
Автор: SuPriTo
Дата сообщения: 03.09.2015 11:12
sammozg
Реализуй свою собственную DLL и там реализуй всю работу с ADO
Автор: ant0ni02004
Дата сообщения: 03.09.2015 11:33
sammozg
а почистить никак.
только сервис перестартовывать время от времени.
SuPriTo
DLL не поможет, а вот отдельный процесс - да. но это сколько же заморачиваться с ним...
Автор: SuPriTo
Дата сообщения: 03.09.2015 11:41
ant0ni02004

Цитата:
вот отдельный процесс - да. но это сколько же заморачиваться с ним...

А что с ним заморачиваться, данные по pipe или filemapping передаешь и усе.
Есть под это готовые компаненты. _http://www.cromis.net/blog/downloads/
"Cromis IPC" - это как пример готового решения для обмена данными через Pipe.

Автор: Frodo_Torbins
Дата сообщения: 03.09.2015 11:56
sammozg
ADO не даст гибко себя настроить. Нужно либо от него отказаться, либо запускать взаимодействие с БД в отдельном процессе, и периодически его убивать.
Автор: sammozg
Дата сообщения: 03.09.2015 12:43
SuPriTo
благодарю за совет но всё-же заморачиватся придётся много, что-бы получить в режиме реального времени
Frodo_Torbins
кроме ADO я нисчем не работал и описания не видел (в книгах по программированию БД все про ADO пишут)... видимо придётся DBE изучать...

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.