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

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

Автор: Maks150988
Дата сообщения: 06.03.2010 16:04
AviDen
А, вот оно что. Тогда понятно. Буду знать.
Автор: AviDen
Дата сообщения: 06.03.2010 16:48
Maks150988
Кстати, включу-ка я функционал ITaskBarList в своего наследника от TForm...
Автор: KurkSS
Дата сообщения: 07.03.2010 22:41
Народ, а вот подскажите как быть в такой ситуации.....

вот есть такая чтока как dll
функция может быть описана на любом языке програмирования, а моя програма может
её использовать.

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

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

Как это делаеться????
Если смысл создать эту сущьность ввиде OLE обьекта... тогда вопрос где можно почитать
как создать такое.......
ЗЫ:вопрос чисто теоретический.... тоесть без конкретизации на 2 вопросе....


2 вопрос....
у меня будут соревноваться несколько сущностей, (см вопрос 1)
если учитывать что количество обьектов будет просто огромное под 100 тысяч... тоесть никакой оперативы не хватит.... как можно выйти из такой ситуации....
ЗЫ - сущности это базовый алгоритм работы и накопления знаний.... их несколько....
а обьектов будет под 100 тысяч.... у них знания и опыт будет разный...
Автор: VadimLou
Дата сообщения: 08.03.2010 02:44
1 - ole или интерфейсы. А почитать - есть даже книги типа Использование COM в Delphi.
2 -
Цитата:
несколько сущностей

Цитата:
просто огромное под 100 тысяч
- то несколько, то 100 тысяс - ты разберись ... 100 тыс - это не много, если они не будут конкурировать по доступу на изменение к одному ресурсу... А так вообщето существуют мьютексы, семафоры, критические секции, пулы... для удобства использования этого хозяйства существуют всякие обёртки в виде классов (TRWS - read write synchronizer, ...) В общем хватает как описаний , так и примеров в книгах ...



Добавлено:
Odysseos
Спасибо за

Цитата:
Windows 7 Components

Автор: Frodo_Torbins
Дата сообщения: 08.03.2010 11:10
KurkSS
Кроме COM можно еще применить подход из WinAPI. Библиотека реализует набор функций для работы с объектами, а первый параметр каждой функции - хендл или проще говоря номер объекта. Т. о. объекты живут внутри библиотеки, а вы лишь управляете ими извне. Этот подход хорош тем, что "объекты" не обязательно реализовывать как настоящие объекты, благодаря этому можно сэкономить ресурсы.
Автор: KurkSS
Дата сообщения: 08.03.2010 11:37

Цитата:
- то несколько, то 100 тысяс - ты разберись ...

А Внимательно почитать - сущность это класс, а 100тыс бедет экземпляров класов

Frodo_Torbins
Цитата:
Т. о. объекты живут внутри библиотеки,

а можно ключевые слова .... что искать для чтения????

Автор: Frodo_Torbins
Дата сообщения: 08.03.2010 13:00
KurkSS

Цитата:
а можно ключевые слова .... что искать для чтения????

Ну про WinAPI я уже сказал, что еще почитать... даже не знаю. Ну вот небольшой примерчик могу показать:
[more]
Код: [no]library LikeWinAPI;

uses
SysUtils, Math, Classes;

type
hMyObject = Integer;
TMyObject = packed record
FFirst: string;
FSecond: Integer;
FEnabled: Boolean;
end;

ErrorCode = Integer;

const
err_OK = 0;
err_SmallBuffer = 1;
//...

var
MyObjects: array of TMyObject;

function Create(var NewObj: hMyObject): ErrorCode; stdcall;
begin
SetLength(MyObjects, Length(MyObjects) + 1);
NewObj := Length(MyObjects) - 1;
Result := err_OK;
end;

function Enable(o: hMyObject): ErrorCode; stdcall;
begin
//здесь проверки
MyObjects[o].FEnabled := True;
Result := err_OK;
end;

function SetFirst(o: hMyObject; str: PChar; len: Integer): ErrorCode; stdcall;
begin
//проверки
SetLength(MyObjects[o].FFirst, len);
StrLCopy(PChar(MyObjects[o].FFirst), str, len);
Result := err_OK;
end;

function GetFirst(o: hMyObject; str: PChar; var len: Integer): ErrorCode;
stdcall;
begin
if str = nil then
begin
len := Length(MyObjects[o].FFirst);
Result := err_OK;
Exit;
end;

if len < Length(MyObjects[o].FFirst) then
Result := err_SmallBuffer
else
Result := err_OK;

len := Min(len, Length(MyObjects[o].FFirst));
StrLCopy(str, PChar(MyObjects[o].FFirst), len);
end;

function DoSomeJob(o: hMyObject): ErrorCode; stdcall;
begin
//...
Result := err_OK;
end;

function Delete(o: hMyObject): ErrorCode; stdcall;
begin
//...
Result := err_OK;
end;

exports
Create,
Enable,
GetFirst,
SetFirst,
DoSomeJob,
Delete;

begin
end.[/no]
Автор: Odysseos
Дата сообщения: 08.03.2010 15:47
VadimLou

Не за что

...Надо отметить, у этих компонентов есть один баг (хотя, подозреваю, он будет у всех компонентов, пользующихся именно таким описанием интерфейса с safecall-моделью вызовов - просто потому, что в таких условиях их едва ли кто тестирует, я сам совершенно случайно наткнулся) - при запуске приложения в случае, если системным shell'ом назначен не обычный explorer.exe (а, к примеру, Total Commander) - они в конструкторе выкидывают safecall exception.

Чтоб исправить - надо найти все вызовы HrInit, и обрамить их в:

Код:
try
FTaskbar.HrInit;
except
on E: ESafecallException do begin
FTaskbar := nil;

Exit;
end;
end;
Автор: DmitryKz
Дата сообщения: 08.03.2010 20:33
Ребята, посоветуйте по такому вопросу:
в грид из бд (в ней около 100 тыс. записей) подгружается отфильтрованный список слов.
Фильтрация происходит по первым символам вводящегося в эдите слова. Например, пользователь набрал в Edit букву 'а', программа построила запрос вида:
query:='SELECT * FROM WORDS WHERE WORDVAL STARTING WITH '+#39+
word+#39+' ORDER BY WORDVAL'
передала датасету, грид обновился - появились все слова из БД, начинающиеся на букву 'а'. Ввел следующий символ 'б' - грид обновился - в нем теперь слова начинающиеся на 'аб' и т. д. и т. п.
Проблема в том, что иногда (даже вообще-то довольно часто) первая фильтрация (по одному, первому символу) происходит ну очень долго: и 5 секунд может и даже 10.
Посоветуйте, как можно было бы ускорить этот процесс. БД - Firebird embedded, компоненты для доступа - Фибы...
Автор: KurkSS
Дата сообщения: 09.03.2010 00:05
Frodo_Torbins
Цитата:
примерчик могу показать:

SetLength(MyObjects, Length(MyObjects) + 1);
NewObj := Length(MyObjects) - 1;Type incompatable TMyObjects and Integer

Вообщем рекордам в куче я умею выделять память....
Спасибо -
все переменые которые функциями длл создаються:
1)Доступны напрямую из программы? ведь нет
2)если длл выгрузить то ведь и данные тютю....
я ктому что прикольный вариант но блин опасный......

Слушай... а что если обьявить TMyObjects и в длл и в програме.... создавать масив в програме а функции дллевской передовать адрес ???
я к тому что она из длл увидит этот адрес.... не случиться что иногда винда будет выдавать
ПАМЯТЬ НЕ МОЖЕТ БЫТЬ РИИД или чтото типа того???
Автор: YuriyRR
Дата сообщения: 09.03.2010 00:52

Цитата:
DmitryKz


Цитата:
первая фильтрация (по одному, первому символу) происходит ну очень долго

1.Не делать первую фильтрацию, фильтровать при условии 2 и более буков (первая фильтрация обычно никому и не нужна)
2. SELECT TOP 100 отбирать столько записей сколько влезет в грид. Далее можно навесить обработчики на PgUp Down и т.д или в трэде качать и из него показывать
3. Там еще желательно, чтоб и слова в предложениях искались
типа зубная паста мятная - ищем на па и находим. тогда еще и словарь строим
СЛОВО - ID записи
Автор: ShIvADeSt
Дата сообщения: 09.03.2010 01:37
DmitryKz
Вместо Едита используй правильный контрол - LookupBox. Он как раз и занимается тем, что по первым буквам ищет нужную запись. Тебе остается только выводить в грид отсортированный список., а далее при вводе в лукапе буков в гриде будет производиться позиционирование на первый соотв элемент. Либо делать фильтрацию при нажатии на кнопку например Ентер. То есть пользователь ввел несколько букв, нажал ентер - получил выборку.
Автор: snike555
Дата сообщения: 09.03.2010 04:59
DmitryKz
Я бы посоветовал поставить таймер. Искать не сразу после ввода символа, а напечатал символ, таймер сбился и включился сново, если прошло 0.5 сек, то происходит поиск. Если после первого символа ищёт уже нормально, то можно таймер только на 1вый символ сделать.
Автор: Cryogen2003
Дата сообщения: 09.03.2010 07:54
YuriyRR
А вот с этого места поподробнее. Есть ли работающий пример, как сделать так, чтобы определенная часть данных подгружалась откуда-то (например из оракла, а другая часть наоборот прибивалась в памяти)?
Автор: greenpc
Дата сообщения: 09.03.2010 08:47
Cryogen2003

Цитата:
определенная часть данных подгружалась

подгружает небольшой кусок данных
смотря чем Вы пользуетесь
1. DOA - dataset св-во queryallrecords - flase (кол-во readbuffer)
2.ODAC - dataset св-во FetchAll (кол-во FetchRows)
Автор: Cryogen2003
Дата сообщения: 09.03.2010 08:55
greenpc
Пользуюсь DOA. По поводу QueryAllRecords это понятно. Что по поводу остального? По крайней мере я там не нашел, чтобы была возможность загружать одну часть, а другую часть из памяти выгружать.
Автор: greenpc
Дата сообщения: 09.03.2010 09:05
Cryogen2003

Цитата:
была возможность загружать одну часть, а другую часть из памяти выгружать

что Вы под этим подразумеваете?
Автор: jonikDk
Дата сообщения: 09.03.2010 09:05
Cryogen2003
ну например для ODAC устанавливаешь свойство FetchRows = 100 и просто ходишь по простому гриду с записями когда ты доходишь до 101 записи DataSet сам фетчит следующие 100 записей и т.д.
Для DOA я думаю аналогично.
Автор: snike555
Дата сообщения: 09.03.2010 09:19
Cryogen2003

Цитата:
По крайней мере я там не нашел, чтобы была возможность загружать одну часть, а другую часть из памяти выгружать.

А вам это зачем если не секрет? На сколько знаю есть ограничения в 100метров в PL\SQL Developer, раз это разработчики DOA, то возможно это ограничение существует в самих компонентах.
Но на самом деле нужно снабдить пользователя удобным фильтром и не заморачиваться такими вопросами.
Автор: Cryogen2003
Дата сообщения: 09.03.2010 09:24
greenpc
jonikDk
Ну все очень легко, очень бы хотелось, чтобы в том же примере, что написал jonikDk, было так. Доходишь до 101 записи, DOA подгружает еще 50 записей, а первые 50 удаляет из памяти. Было бы точно очень удобно. Правда конечно было бы ограничение не по 100 записей в буфере, а думаю тысячи на 2, но все же.
Просто часто бывает так, что клиентам хочется как бы видеть сразу "все" записи на экране и не пользоваться никакими фильтрами и поисками (а поиск только Ctrl+F - типа из-за разряда, если Ёксель так умеет, то почему ваша программа не умеет. И не я не могу доказать, не бизнес-аналитики это этим тетенькам в 70 лет). А число транзакций по счетам может достигать и 70000 в обычный день и в последний день месяца под лям в день.
Автор: greenpc
Дата сообщения: 09.03.2010 09:36
Cryogen2003
да пожалуйста
1 вариант - курсор в пакете.
2. вариант поле rownum
а вобщето рекомендую почитать Кайт'а
_http://www.oracle.com/global/ru/oramag/mayjune2007/w_dev_asktom56.html

Цитата:
хочется как бы видеть сразу "все" записи на экране

понимаете человек с "захода" не сможет обработать визуально более 300-500
записей.

Цитата:
70000 в обычный день и в последний день месяца под лям в день

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

Цитата:
DOA подгружает еще 50 записей, а первые 50 удаляет из памяти

вы задали запрос базе - получили "кусок" данных. а не весь объем их - так зачем же их удалять?
Цитата:
поиск только Ctrl+F

опять же только 2 варианта
1. таблица в памяти (kbmemtable)- все данные (+ удобные сортировки на клиенте)
2. мучать сервер запросами
Автор: Cryogen2003
Дата сообщения: 09.03.2010 09:50
greenpc
Батько Кайта читал раньше регулярно, сейчас пока собственных знаний на стороне оракла хватает.
1. По поводу курсора и rownum это все понятно и знаю как пишеться и делается.
2. Ну все эти бабушки типа так привыкли работать и переучиваться они не хотят. Или как они выражаются - "не учите нас работать".
По поводу того, зачем удалять записи из памяти? А все очень легко - например 50000 записей при 30 столбцах в TOracleDataSet - это примерно гиг оперативной памяти. Столько же занимает памяти в режиме Fast и в TkbmDataSet. Если поставить режим Small, то это будет мегов 100, что тоже не особо хорошо.
Если пользоваться еще и группировкой в девовском гриде, то добавить еще метров 300. Вот так.
Вообще и так понятно, что бабулек надо выгонять либо переучивать, бизнес-аналитиков менять, но я скорее сам уволюсь, чем это измениться. Так что вот и пытаюсь найти решение, так как видел где-то в инете демки (в виде видео) на эту тему (было лет 10 назад) и там практически прозрачно все работало (бесшовно) и памяти ело все очень мало (а табличка было на несколько лимонов записей).
Автор: greenpc
Дата сообщения: 09.03.2010 09:58
Cryogen2003

Цитата:
группировкой в девовском гриде

если он не в gridMode - то считаете что все данные у вас в памяти без всяких делений по 1000
Автор: Cryogen2003
Дата сообщения: 09.03.2010 10:01
greenpc
Это я знаю, но кстати их метори тэйбл хорошо относиться к памяти, так же как и TkbmMemDataSet в режиме Small.

Кстати, а чем отличается включенный GridMode от выключенного?
Автор: jonikDk
Дата сообщения: 09.03.2010 10:05
Cryogen2003
ну выбора особо нет: либо все записи показывать - много оперативы, либо по частям.
Оператива по деньгам сейчас не проблема. Закачивай все в cxGrid и дальше пусть делают все тоже самое что и в эксель.
Либо может действительно сделать в отдельном потоке подгрузку записей ?
Про выгрузку записей если честно не понял, зачем выгружать то что уже посмотрели, вдруг эти записи понадобятся еще раз? Что их заново подгружать ?

Кстати однонаправленный курсор это не оно ?? Только с гридом он по моему не очень дружит
Автор: Frodo_Torbins
Дата сообщения: 09.03.2010 10:08
KurkSS

Цитата:
Type incompatable TMyObjects and Integer
Приведенный мной код прекрасно откомпилировался в D7.

Цитата:
все переменые которые функциями длл создаються:
1)Доступны напрямую из программы? ведь нет
Распределением памяти под "объекты" должна управлять исключительно dll. Иначе допустим у вас dll будет на делфи, а программа скажем на джава. Как вы в этом случае собираетесь распределять память?

Цитата:
2)если длл выгрузить то ведь и данные тютю....
Можно реализовать пару методов, которые будут сохранять и загружать массив рекордов в предоставленный буфер. Будет что то на подобие GetFirst/SetFirst (вообще это тема отдельного разговора). Главное, чтобы программа не пыталась менять эти данные самостоятельно.
Автор: DmitryKz
Дата сообщения: 09.03.2010 10:16

Цитата:
Не делать первую фильтрацию, фильтровать при условии 2 и более буков

При используемых сейчас компонентах все равно иногда задержка несколько секунд случается.
ShIvADeSt
Извинияюсь, если туплю, но что это за кантрол такой - LookupBox и где его взять? В стандартные дблукапы никаких буков ввести невозможно.
Автор: Cryogen2003
Дата сообщения: 09.03.2010 10:21
jonikDk
По поводу какой выгрузки записей? Я не понял.

А так, как я понимаю, что в принципе нормального решения нет. Вероятнее всего надо двигаться в сторону кэширования на диске клиентной стороны, но пока еще не догадался как.

Да я уже практически забил на все это, надо просто чтоб нормально за меня общался бизнес-аналитик и все. Я уже задолбался ругаться.
А так, я пока сделал возможность (переписал чуть класс девовского грида) поиска по Ctrl+F и выделения по столбцам. Жаль что не могу нормально изменить глюк в девовском гриде с выделением строчек по Ctrl, приходить каждый раз править исходник в девках.
Автор: greenpc
Дата сообщения: 09.03.2010 10:22
Cryogen2003
вкраце - все прелести грида - происходят на клиенте (групировка, фильтр..) в памяти
а так как обычный dbgrid
Автор: Cryogen2003
Дата сообщения: 09.03.2010 10:25
greenpc
Дык и при выключенном GridMode абсолютно так же. Стало быть, чего я не понимаю?

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

Предыдущая тема: Clipper 5


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