Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Интернет: Образование, Работа и Бизнес" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
← Январь 2008 → | ||||||
1
|
2
|
3
|
4
|
5
|
6
|
|
---|---|---|---|---|---|---|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
14
|
15
|
16
|
17
|
18
|
19
|
20
|
21
|
22
|
23
|
24
|
25
|
26
|
27
|
28
|
29
|
30
|
Статистика
-1 за неделю
Программирование на Delphi (выпуск 78)
Программирование на DELPHI
Выпуск #78 (31 января 2008 г.)
Если Вы хотите где-либо разместить материалы, представленные на www.delphi.int.ru или в данной рассылке, свяжитесь, пожалуйста, с их автором или ведущим рассылки.
Delphi.int.ru Expert Последние новости
Архив: вопросы и ответы В архив попадают вопросы, срок действия которых истёк. Каждый заданный вопрос действителен в течение одной недели, т.е. ответы на него принимаются именно в этот период. В сегодняшнем выпуске опубликованы вопросы # 326 - 340. Вопросы, на которые не было дано ни одного ответа, не публикуются. Статистика по выпуску: Кол-во вопросов: 15 Вопрос # 327 Доброе время суток Господа эксперты в очередной раз я задался вопросм итак есть у меня готовая заполненная таблица из которой меня интересуют только два столбца... и имеется на форме компонент TDBChart мне необходимо построить с помощью них график, причем таким образом, что бы данный компонент брал значения точек X из одного столбца а соответственно Y из ругого.... и из множества взятых точек строил график.... будьте любезны подскажите как я это могу сделать??? Вопрос задал: Шуваев Алексей Сергеевич - 737 (статус: Посетитель) 1. Отвечает эксперт: Вадим К Ну так в чём проблема? Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 328 Добрый день) Вопрос задал: RedMask (статус: Посетитель) 1. Отвечает эксперт: Alex Van Glukhman Здравствуйте, RedMask! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) Вопрос # 329 Всем Привет! Вопрос задал: Vit2 (статус: Посетитель) 1. Отвечает эксперт: Роман Здравствуйте, Vit2!Надо было хоть код привести.Если в коде всё правильно увеличте timeout. Ответ отправил: Роман (статус: 5-ый класс) 2. Отвечает эксперт: Вадим К Скорее всего в вашем коде нехватает referns и замените идентификацию с Indy на что нибудь мирное - "opera/ua" к примеру. Многие серверы не равнодушны к идентификации. Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 330 Доброе время суток всем. Помогите, кто знаеи как (если можно) в компоненте PopupMenu сделать, так чтобы сбоку меню писалось название программы (либо любой текст) или помещалась картинка Вопрос задал: Дима Гусаков (статус: 2-ой класс) 1. Отвечает эксперт: Евгений Козаченко Нужно установить TMS Component Pack. Там есть такой компонент "AdvPopupMenu". Вот он умеет так делать. Ссылку дать не могу, но поиск же рулит Ответ отправил: Евгений Козаченко (статус: 2-ой класс) 2. Отвечает эксперт: Роман Здравствуйте, Дима Гусаков!Вот по этому адресу: http://sources.ru/magazine/0906/07.html (это архив журнала "Sources.RU Magazine") есть статья об альтернативном способе написать PopupMenu: всплывающее меню – вовсе не меню, а самая обыкновенная форма, и о том, как пидать ей "красивости".Думаю что она поможет в решении проблемы. Ответ отправил: Роман (статус: 5-ый класс) 3. Отвечает эксперт: Вадим К Как вариант, можно отрисовать меню самостоятельно. Получиться дешиво и сердито. Вы сможете нарисовать всё, что подскажет вам ваша фантазия :) Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 331 Такая вот проблема. Написал прогу на Делфи(Работа с базами данных). Но когда удаляю делфи она не идет т.е она рзагружается, но не поддерживает работу с Б.Д. Как сделать чтобы она работала без Делфи и В другой системе, например в Windows 98,2000. Помогите пожалуйста. Буду очень блогадарен. Вопрос задал: mAx (статус: Посетитель) 1. Отвечает эксперт: Alex Van Glukhman Здравствуйте, Рожков Максим Сергеевич! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) 2. Отвечает эксперт: Вадим К Если писали по старым книгам, то 99% BDE - кидайтие его побыстрей. Вариант два, при использовании ADO - жестко прописаный путь к базе. Ответ отправил: Вадим К (статус: Кандидат наук) 3. Отвечает эксперт: Помфюк Владимир Степанович Здравствуйте, Рожков Максим Сергеевич! Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент) Вопрос # 332 Когдая загружаю свою прогу на винде на которой не установлен Delphi и нажимаю на кнопку обработчик события: Вопрос задал: mAx (статус: Посетитель) 1. Отвечает эксперт: Вадим К Ну не знаю, как ещё отвечать на этот вопрос, который изучен вдоль и впоперек. Дело в том, что когда то (1992-1997гг.) Борланд придумала хорошую технологию доступа к данных - BDE. Хорошую на то время. Но на данный момент эта технология НЕ РАЗВИВАЕТСЯ. Многие, старые да и новые книги по делфи почему то упорно игнорирую этот факт (мож им просто лень переписывать?) и толкают BDE как передовую технологию. Ответ отправил: Вадим К (статус: Кандидат наук) 2. Отвечает эксперт: Матвеев Игорь Владимирович Здравствуйте, Рожков Максим Сергеевич! Ответ отправил: Матвеев Игорь Владимирович (статус: Студент) 3. Отвечает эксперт: Alex Van Glukhman Здравствуйте, Рожков Максим Сергеевич! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) Вопрос # 333 Где можно скачать "Сборник задач по Паскалю" Вопрос задал: Просвиринин Руслан Олегович (статус: Посетитель) 1. Отвечает эксперт: Alex Van Glukhman Здравствуйте, Просвиринин Руслан Олегович! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) Вопрос # 334 Приветствую!!!У меня появилось несколько вопросов:1.Как во время выполнения программы узнать все установленные серверы баз данных;2.Как по известному имнеи сервера узнать какие там находятся базы данных;3.Как определить что программа уже запушенна(кроме создания фалов,или записей в файлах)???? Огромное СПАСИБО!!! Вопрос задал: KilkaMS (статус: Посетитель) 1. Отвечает эксперт: Вадим К Просьба на дальше: никогда не намешивайте кучу вопросов в одном вопросе. А если мешаете, то они должны быть хотя бы связаны. Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 335 Здравствуйте! Приложение: Вопрос задал: RedMask (статус: Посетитель) 1. Отвечает эксперт: Помфюк Владимир Степанович Здравствуйте, RedMask! Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент) 2. Отвечает эксперт: Бубырь Александр Николаевич Можно еще дать команду FetchAll после открытия датасета. Это особенность работы компонентов - чтобы не перегружать себя ненужными данными (особенно при больших таблицах и работе по сети), компонент выбирает данные по мере надобности (по команде Next или аналогичной), а FetchAll или Last заставляет загрузить все данные из таблицы или запроса. Ответ отправил: Бубырь Александр Николаевич (статус: 6-ой класс) 3. Отвечает эксперт: Alex Van Glukhman Здравствуйте, RedMask! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) Вопрос # 336 Доброго времени суток господа эксперты. У меня такая проблема. Я хочу сделать так чтобы мою прогу небыло видно в диспетчере задач. Пытался зарегестрировать как сервис не получается. Может я делаю что-то не так плз помогите. Если можно пример кода. Заранее благодарю Вопрос задал: Яковлев Николай Сергеевич (статус: Посетитель) 1. Отвечает эксперт: Роман Здравствуйте, Яковлев Николай Сергеевич!Вот адресок:http://sources.ru/delphi/internet/remote_admin_aibolit.shtml.Это статья Троянец "Айболит" называется. Там есть исходники.Сервер прописывается в windows/system,в автозапуск,не имеет видимого окна и не виден в диспетчере задач. Ответ отправил: Роман (статус: 5-ый класс) 2. Отвечает эксперт: Вадим К Скрыть нормально от диспетчера задач сложно. Единствення задача, которая требует этого - вирусы и трояны(системы удалённого управления - это тоже трояны). Таких людей, которые пишут вредный софт, нужно калечить. Ответ отправил: Вадим К (статус: Кандидат наук) 3. Отвечает эксперт: Alex Van Glukhman Здравствуйте, Яковлев Николай Сергеевич! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) 4. Отвечает эксперт: Denisss Вот статья: Ответ отправил: Denisss (статус: 2-ой класс) Вопрос # 337 Уважаемые эксперты, я только начинаю изучать программирование. Купил книгу В.Кадлеца "Delphi книга рецептов....". Приложение: Вопрос задал: Игорь (статус: Посетитель) 1. Отвечает эксперт: Помфюк Владимир Степанович Здравствуйте, Игорь! Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент) 2. Отвечает эксперт: Федоров Роман Сергеевич Здравствуйте, Игорь! Приложение:
Ответ отправил: Федоров Роман Сергеевич (статус: 2-ой класс) 3. Отвечает эксперт: Alex Van Glukhman Здравствуйте, Игорь! Ответ отправил: Alex Van Glukhman (статус: 7-ой класс) 4. Отвечает эксперт: Вадим К и никто не нависал правильный вариант Ответ отправил: Вадим К (статус: Кандидат наук) 5. Отвечает эксперт: Дима Гусаков Здравствуйте, Игорь! В строке выше вместо J:= J = 10 напиши J:= J + 10; не забывай вконце строки ставить точку с запятой Ответ отправил: Дима Гусаков (статус: 2-ой класс) Вопрос # 338 Приветствую!!!Как можно послать сообщение на др. комп. не используя NET SEND.Вообще разрабатываю ИС и хочу чтобы пользователи могли переписываться из нее.Могу узнать имя машины,и ip тоже не проблема. Вопрос задал: KilkaMS (статус: Посетитель) 1. Отвечает эксперт: Матвеев Игорь Владимирович Здравствуйте, KilkaMS! Ответ отправил: Матвеев Игорь Владимирович (статус: Студент) Вопрос # 339 Приветствую!!!Есть у кого-нибудь текст лицензии OpenSourсe? Вопрос задал: KilkaMS (статус: Посетитель) 1. Отвечает эксперт: Матвеев Игорь Владимирович Здравствуйте, KilkaMS! Ответ отправил: Матвеев Игорь Владимирович (статус: Студент) 2. Отвечает эксперт: Вадим К Да,лицензий много, самой OpenSourse'ной считается GPL (можно даже переводы найти например здесь http://www.infolex.narod.ru/gpl_gnu/gplrus.html, а здесь http://www.linux.kiev.ua/ru/devel/licenses/gpl-explained/ некоторые рассуждения). На данный момент Ричард М. Столлман разрабатывает третью версию этой лицензии, но многие не совсем согласны с ней (читать здесьhttp://citkit.ru/articles/230/). Ответ отправил: Вадим К (статус: Кандидат наук) Вопрос # 340 Здравствуйте! Вопрос задал: HotMan (статус: Посетитель) 1. Отвечает эксперт: Вадим К В общем виде эта задача нерешабельна. тоесть нет точного способа решить. Запомните, всё что написано одним человеком, гарантировано может быть сломано другим. Проблема только во времени. Новсё же пару идей могу дать. Можно скачать StarForce - но он достаточно дорог, и если у вас это еденичная программа, то она врядли окупиться. Ответ отправил: Вадим К (статус: Кандидат наук) 2. Отвечает эксперт: Матвеев Игорь Владимирович Здравствуйте, Kardonsky Roman Viktorovich! Ответ отправил: Матвеев Игорь Владимирович (статус: Студент) 3. Отвечает эксперт: Новаковский Юрий Аврамович Здравствуйте, Kardonsky Roman Viktorovich! Ответ отправил: Новаковский Юрий Аврамович (статус: 4-ый класс) » Найти все предыдущие уроки можно на www.delphi.int.ru в разделе "Статьи". Последние 3 урока: Циклы - цикл с предусловием и цикл с постусловием
ВведениеНа прошлом уроке мы познакомились с циклами и разобрались, как использовать цикл по переменной. Сегодня мы разберём оставшиеся два вида циклов - цикл с предусловием и цикл с постусловием. Они очень похожи и просты в использовании. ЗадачаОпределить количество натуральных чисел, рассматривая их в порядке возрастания, сумма кубов которых не превышает 50000. Т.е. мы должны последовательно суммировать кубы чисел 1, 2, 3, ..., и делать это до тех пор, пока сумма не достигнет 50000, а в результате должны узнать, сколько чисел было пройдено. Понятно, что решить задачу лучше использованием цикла. Но будет ли решение с циклом FOR оптимальным? Конечно, можно задать диапазон пробегаемых значений от 1 до 50000 - количество чисел точно будет найдено (очевидно, это кол-во будет даже менее 50, ведь 50^3 >> 50000). Но в этом случае придётся ставить дополнительное условие на значение суммы и выполнение команды Break. Есть способ проще! Цикл WHILE - цикл с предусловиемЦикл WHILE (англ. "пока") - цикл, в котором условие находится перед телом цикла, а сам цикл выполняется до тех пор, пока условие не станет ложным. Общий вид: WHILE {условие} DO {действия} В качестве условия задаётся логическое выражение. Те операции, что будут выполняться в цикле, называются телом цикла. Особенностью цикла с предусловием является то, что он может не выполниться ни разу - это произойдёт, если указанное условие изначально будет ложным. При этом, цикл может и стать "вечным" - если условие никогда не примет значения False. Именно поэтому следует следить за тем, чтобы всегда присутствовали условия для завершения работы цикла. Решение задачи с помощью цикла WHILE Вернёмся к нашей задаче. С помощью цикла с предусловием задача решается очень просто. Во-первых, нам потребуется переменная, в которой будет храниться текущее обрабатываемое число - это будут числа 1, 2, 3 и т.д. Во-вторых, ещё одна переменная потребуется для хранения суммы кубов чисел. Всё, этого достаточно. Теперь разберёмся, что писать в теле цикла. Там мы должны: а) увеличивать переменную-счётчик на единицу, чтобы последовательно проходить числа; б) увеличивать сумму на куб текущего числа. Условием цикла будет главное условие нашей задачи - достижение суммой 50000. Вот что получается: procedure TForm1.Button1Click(Sender: TObject); var s,i: integer; begin i:=0; s:=0; while s < 50000 do begin Inc(i); Inc(s,i*i*i); end; Label1.Caption:=IntToStr(i-1) end; В данном случае процесс "повешен" на кнопку (Button1), а результат выводится в текстовую метку (Label1). Вы спросите, почему выводится i-1, а не само число i ? Всё просто. Ведь переменная-счётчик увеличивается после того, как проверяется условие цикла, а значит и результат получится на единицу больше. Удостовериться в этом можно, добавив в тело цикла вывод промежуточных результатов (в примере - в текстовое поле Memo1): Memo1.Lines.Add(IntToStr(s)+' : '+IntToStr(i)); Цикл REPEAT - цикл с постусловиемЗавершает тройку циклов цикл с постусловием - REPEAT (англ. "повтор"). Примечательно, что этого цикла во многих языках программирования нет - есть только FOR и WHILE. Между тем, цикл с постусловием очень удобен. Работает цикл точно так же, как и WHILE, но с одним лишь отличием, следующим из его названия - условие цикла располагается после тела цикла, а не до него. Общий вид: REPEAT {действия} UNTIL {условие выхода из цикла}; Есть несколько моментов, на которые стоит обратить внимание. Во-первых, в качестве условия задаётся уже условие выхода из цикла, в то время как в цикле WHILE задаётся условие продолжения цикла. Во-вторых, при наличии нескольких команд, которые помещаются в тело цикла, заключать их в блок BEGIN .. END не нужно - зарезервированные слова REPEAT .. UNTIL сами составляют аналогичный блок. Цикл с постусловием, в отличие от цикла с предусловием, всегда выполняется хотя бы один раз! Но, как и цикл WHILE, при неверно написанном условии цикл станет "вечным". Решение задачи с помощью цикла REPEAT Решение нашей задачи практически не изменится - всё останется, только условие будет стоять в конце, а само условие изменится на противоположное: procedure TForm1.Button2Click(Sender: TObject); var s,i: integer; begin i:=0; s:=0; repeat Inc(i); Inc(s,i*i*i); until s >= 50000; Label1.Caption:=IntToStr(i-1); end; Команды Break и ContinueКоманда Break, выполняющая досрочный выход из цикла, работает не только в цикле FOR, но и в циклах WHILE и REPEAT. Аналогично, команда Continue, немедленно запускающая следующую итерацию цикла, может использоваться в циклах WHILE и REPEAT. Как остановить цикл?Очень часто спрашивают, как написать такой цикл, который можно было бы остановить нажатием кнопки на форме, или, к примеру, клавишей [Esc]. В простейшем случае реализовать такой механизм достаточно просто. Однако, данный метод является не совсем верным - есть более удобные и правильные средства для организации таких операций. Тем не менее, рассмотрим пример. Задание: при нажатии кнопки "Старт" программа начинает генерировать случайные комбинации из латинских букв (верхнего регистра) длиной 10 символов и все эти комбинации отображаются в текстовом поле TMemo. При нажатии кнопки "Стоп" генерация должна быть прекращена. Каким образом решить поставленную задачу? Сначала сделаем акцент на механизме остановки. Понятно, что в данном случае нужно задать вечный цикл, да-да, самый настоящий, но каким образом предусмотреть его остановку? Очевидно, что выбор падает либо на WHILE, либо на REPEAT. Остановить цикл можно либо изменив значение логического выражения, заданного для цикла, либо вызвав команду Break. Вопрос стоит теперь в том, как при нажатии кнопки "Стоп" изменить условие цикла, описанного в обработчике кнопки "Старт". Ответ прост - использовать ту память, которая доступна обработчикам обеих кнопок. Итак, заведём глобальную переменную, которая будет видна во всей программе. Глобальные переменные описываются над словом implementation модуля, там, где идёт описание формы: var Form1: TForm1; Stop: Boolean = False; В этой логической переменной мы будем хранить состояние процесса. Изначально будет стоять значение "ложь", а когда пользователь щёлкнет по кнопке "Стоп", мы изменим его в "истина". На форме разместим Memo1 (TMemo) и 2 кнопки: Button1 ("Старт"), Button2 ("Стоп"). У кнопки "Стоп" поставим Enabled = False, т.е. выключим её. Сразу приведу обработчики обеих кнопок, после чего подробно разберём их работу: procedure TForm1.Button1Click(Sender: TObject); var s: string; c: byte; begin Button2.Enabled:=True; Button1.Enabled:=False; Stop:=False; while not(Stop) do begin s:=''; for c := 1 to 10 do s:=s+Chr(Random(Ord('Z')-Ord('A')+1)+Ord('A')); Memo1.Lines.Add(s); Application.ProcessMessages end end; procedure TForm1.Button2Click(Sender: TObject); begin Stop:=True; Button2.Enabled:=False; Button1.Enabled:=True; end; Начнём с кнопки "Стоп" (Button2). При её нажатии: Теперь кнопка "Старт" (Button1): А теперь более подробно о том, что происходит в теле цикла. Начнём с генерации строки символов. Напомню, что строки можно складывать. Если сложить строку 'A' со строкой 'B', то получится строка 'AB'. Именно этот приём здесь и использован. Сначала мы делаем строку пустой, а затем последовательно добавляем в неё 10 произвольных символов. Как происходит добавление... Ну естественно с помощью цикла на 10 итераций. А вот выбор случайной из латинских букв не совсем прост и не для всех очевиден. Конечно, можно было заранее записать все буквы куда-либо (например, в массив, или в другую строковую переменную), а затем брать их оттуда. Но это не совсем хорошо, ведь можно сделать гораздо проще. В данном случае решающим фактором является то, что латинские буквы в кодовой таблице символов идут по порядку. Т.е. 'A' имеет некоторый код n, 'B' имеет код n+1 и т.д. - весь алфавит идёт последовательно, без разрывов. Убедиться в этом можно с помощью программы "Таблица символов& quot;, которая есть в Windows. Вернёмся к нашей задаче. Мы должны выбрать случайную из букв 'A'..'Z'. Так как коды этих символов последовательны, то мы должны выбрать произвольное число от код_символа_A до код_символа_Z. Напомню, что для выбора случайного числа используется функция Random(n), возвращающая случайное число от 0 до n-1. Недостаток функции в том, что она берёт числа всё время от нуля, а код символа 'A' уж явно не 0. Но и здесь ничего сложного нет: сначала узнаём "ширину"
диапазона кодов - из кода символа 'Z' вычитаем код символа 'A'. Не забываем прибавить 1, иначе буква 'Z' никогда не попадёт в строку, т.к. число берётся от 0 до n-1. Ну и дальше мы делаем сдвиг числа на код символа 'A'. Для справки: очень часто, глядя на такой код, говорят, что он неоптимален - мол, коды символов будут постоянно рассчитываться (речь о функции Ord). Однако знающие люди никогда этого не скажут, ведь в Delphi есть маленькая хитрость: компилятор вычислит эти значения ещё на этапе компиляции и в программе они будут просто константами. Т.е. Ord('Z') и Ord('A') в программе не будут считаться никогда - там будут стоять вполне реальные числа, а значит никакого избытка вычислений идти не будет. Более того, даже вычитание будет произведено на этапе компиляции, ведь оба слагаемых являются константами. Мы пишем Ord('A') и Ord('Z') только из-за того, чтобы не лезть в кодовую таблицу, и не смотреть вручную коды этих символов. Кроме того, если вместо этого записать реальные коды, другой человек может испытать затрудение при чтении кода - он ведь не знает, откуда вы взяли эти числа и не помнит всю кодовую таблицу, чтобы определить, каким символам эти числа соот ветствуют. Далее полученная строка s добавляется в Memo1 уже известным способом. А вот последняя строка в теле цикла - это маленькая хитрость. В одном из уроков об этой команде уже упоминалось. Дело в том, что при отсутствии этой команды программа просто зависнет с точки зрения пользовательского интерфейса - никаких изменений в Memo видно не будет, да и само окно перестанет реагировать на щелчки. На самом деле, конечно, программа будет работать, в памяти генерация строк будет идти полным ходом... Команда Application.ProcessMessages заставляет приложение обработать всю очередь задач, в том числе по отрисовке окна программы и элементов формы. Если при генерации каждой строки это будет происходить, программа будет выглядеть вполне живой - можно будет легко переместить окно по экрану и, что самое главное, нажать на заветную кнопку "Стоп". Ради эксперимента попробуйте убрать эту строку, и посмотреть, что получится. Как было сказано ранее, такой способ является не совсем верным. В серьёзных программах программировать процессы таким образом не допускается. Для параллельного выполнения операций, которые не должны мешать друг другу, существуют потоки, т.е. когда процессы работают одновременно, а сама программа при этом ими управляет. У потоков очень много преимуществ - поток можно легко остановить, можно задать его приоритет и др. Работа с потоками достаточно сложна для начинающих программистов, поэтому мы пока ограничимся тем примером, что был приведён выше. В конце концов, наш урок посвящён циклам. Подводим итогИтак, мы познакомились с циклами - специальными конструкциями языка для многократного выполнения одних и тех же команд. Как правило, циклы встречаются практически везде, даже в простых на первый взгляд программах. Что уж говорить о каких-либо вычислениях или работе с базами данных... Оцените данный урок (1 - плохо, ..., 5 - отлично):
-1- -2- -3- -4- -5-. Комментарии в тексте письма приветствуются.
Самые популярные статьи на сайте: ∙ Создание непрямоугольных форм в Delphi Знакомство с SQLiteАвтор: Вадим К ВступлениеЧасто на форумах, да и здесь на сайте спрашивают, какую базу данных выбрать. Хочу сегодня представить вам ещё один движок БД, у которого есть свои преимущества. Называется этот движок SQLite. Итак, его преимущества:
Но есть и недостатки:
Начальные приготовленияДля работы с этой базой нам в обязательном порядке понадобится сама dll. Её можно скачать с сайта http://www.sqlite.org/ или взять в архиве к статье. С dll можно работать напрямую, но куда удобнее использовать обертку в виде классов. Есть обертка, которая подобна делфийскому TTable, есть и драйвер для ODBC, который позволяет работать с базой посредством TADOTable. И если первый вариант ещё интересен, то вариант с использованием через ADO лишен смысла – многие «вкусности» теряются. В архиве вы найдете разные классы для работы. Я работаю с одним с них, и дальше буду описывать его. Главное преимущество – он без компонентов. Хотя кому-то это и покажется сложным, но можно, например, делать консольные приложения. Также неплохо иметь ещё одну программу – программу для редактирования баз данных. Что-то в виде Database Desktop, только для SQLite. Такая программа есть и она бесплатна. Скачать можно здесь http://sqlitebrowser.sourceforge.net/ или опять же, взять в архиве. Хотя программа и проста, свою работу выполняет отлично. Мы не будем составлять базу в программе, а пойдём как настоящие кодеры - научимся создавать её в своей программе. Работа с БДДля примера мы создадим маленькую базу из одной таблицы. У нас будет одно автоинкрементое поле и два строковых. Запускаем Delphi. Создаём новый проект. В папку с проектом копируем файлы sqlite3.pas, sqliteTable3.pas и sqlite3.dll. Дальше их надо подключить к проекту. Выбираем в меню Project – Add to project и добавляем эти файлы. Также не забываем сделать File – Use unit и выбрать эти же файлы, но предварительно переключившись на главный юнит. После строки {$R *.dfm} допишем Var sldb: TSQLiteDatabase; - это будет глобальный объект для работы с базой. Хотя лучше сделать его свойством формы. Кто понимает – сделает :-) Делаем подключение к базе. Для этого впишем такой код в FormCreate: procedure TForm1.FormCreate(Sender: TObject); begin sldb := TSQLiteDatabase.Create('test.db'); try if not sldb.TableExists('test') then sldb.ExecSQL('CREATE TABLE Test (id INTEGER PRIMARY KEY, T1 TEXT, T2 TEXT)'); except ShowMessage('При создании базы произошла ошибка.'); Application.Terminate; end; end; Согласитесь, всё предельно просто. На ADO, если бы базы не было, пришлось бы делать дополнительную работу и писать процедуру не на одну строку. Суть этого кода следующая – открыть файл test.db. Потом проверить, есть ли в нём таблица test. Если нет – создать, выполнив запрос. Если файла не будет, то он будет создан. Если же при создании таблицы у нас что-то не сложилось – закроем приложение. Также не забываем, что за собой надо чистить. procedure TForm1.FormDestroy(Sender: TObject); begin sldb.Free; end; Теперь научимся добавлять записи. Ставим кнопку с заголовком "Create records" ("Создать записи") и создадим для неё такой обработчик procedure TForm1.Button1Click(Sender: TObject); const n = 100; // сколько записей хотим добавить var i: integer; t: cardinal; //для подсчёта времени begin t := GetTickCount; for i := 0 to n - 1 do sldb.ExecSQL('insert into test (t1,t2) values("'+inttostr(random(1000))+'","'+inttostr(random(1000))+'")'); t := GetTickCount - t; ShowMessage(Format('Добавленно %d записей за %d мс',[n,t])); end; Теперь научимся отображать записи и выполнять запросы к базе. Поставим TMemo, TEdit и кнопку "Select" ("Выбрать"). По нажатию на кнопку будем искать записи в поле T1, которые начинаются на те же цифры, что мы ввели в Edit, и будем их выводить. procedure TForm1.Button2Click(Sender: TObject); var sltb:TSQLiteTable; i:integer; begin Memo1.Lines.BeginUpdate; try Memo1.Clear; sltb := sldb.GetTable('select t1,t2 from test where t1 like "'+Edit1.Text+'%"'); try for i := 0 to sltb.Count - 1 do begin Memo1.Lines.Add(sltb.FieldAsString(0)+', '+sltb.FieldAsString(0)); sltb.Next; end; finally sltb.Free; end; finally Memo1.Lines.EndUpdate; end; end; Как можно заметить, ничего особенного. Всё очень похоже на то, что доступно в BDE. А картинки как?Не знаю почему, но с другими базами добавление картинок для меня – большая трагедия. И если ещё с BDE всё спокойно, то с ADO сплошные приключения :-) В SQLite есть специальный тип поля – BLOB (он есть и во многих других БД). Итак, общий алгоритм добавления бинарных данных в базу: - Добавить запись с помощью INSERT. Но не включать бинарное поле (BLOB). - Узнать ID добавленной записи (есть специальный метод у TSQLiteDatabase – GetLastInsertRowID – возвращает значение последнего добавленного автоинкрементого поля. Его имя не обязано быть ID. Важно только наличие) - С помощью UPDATE обновить данное поле, добавив к нему изображение/BLOB (для этого опять же есть метод UpdateBlob. Он принимает два параметра. Первый – сиквел-выражение вида "UPDATE моя_таблица SET поле_блоба = ? WHERE поле_id = сохранённый_id". Надо только заполнить по шаблону 4 слова. Второй параметр – подготовленные в TStream данные. Например, var f: TFileStream; … f := TFileStream.Create('FileName',fmOpenRead));. Саму реализацию оставляю как домашнее задание :-) РезультатыВсего несколько строк, а имеем сколько преимуществ. На этом движке я построил несколько приложений, используя его для хранения информации. По субъективным ощущениям работает база в несколько раз быстрей, чем аналогичная на Access. Приложение при старте запускается моментально, ведь ему не надо инициализировать COM-объекты. Пробуйте, дерзайте, экспериментируйте! Разделы: Статьи | Компоненты | Plug-in's | Документация | Исходники | Программы | Игры | Изображения Уважаемые читатели! Отправляйте полезные компоненты/модули, исходники, собственные программы/игры, документацию - книги, учебники и они будут размещены на сайте.
Ведущий раздела: Bruder Чайники веб-дизайна (часть II) К сожалению, опыты по дрессировке чайника и его использованию в качестве рабочего животного пока не привели к положительным результатам. Хотя чайник и способен следовать формальным критериям (в случае подкормки), для работы по структурной разметке он не пригоден, так как не осознает структуры документа. Эксперимент показал, что наиболее сообразительные чайники в принципе способны проверять свой документ валидатором и с нескольких попыток добиваться полной синтаксической грамотности, однако ни о какой структурной грамотности речи идти не может. В частности, чайники применяют тэги заголовков (например, <H5>) для выделения (вместо <STRONG>), а списки организуют не с помощью тэгов списков, а посредством перевода строк тэгом <BR> и ручной расстановкой маркеров списка. Это происходит из-за того, что чайники, не способные понять структуры и тем более - смысла текста в опытном документе, стремятся скопировать единственное, что понимают, - внешний вид документа в известных им браузерах. Кстати, при столкновении с неизвестным браузером чайник обычно проявляет либо безразличие, либо агрессию. Исследовательский интерес у чайника, в отличие от многих других животных, выражен крайне слабо. Они крайне настороженно относятся ко всему, что может нарушить их привычки и сложившиеся рефлексы. Чайнику недоступны человеческие категории профессиональной этики и заботы о пользователе. Чайник не способен мотивироваться удобством для пользователя. Редкие случаи, когда чайнику удавалось сделать удобный сайт, объясняются в основном грамотной установкой экспериментатора, обеспечившего не только подкормку за действия, повышающие удобство, но и наказание за действия, ухудшающие usability сайта. Таким образом, моральных соображений для чайника не существует. Совести у него нет и быть не может. Кроме того, чайник не способен признавать чьего-либо авторитета и совершенно не задумывается о будущем. Интересы чайника по времени не простираются дальше ожидания подкормки за выполняемую в данный момент работу. Внутри популяции чайников нередко устанавливается своеобразная иерархия. Доминирующими особями становятся те, кто испытал на себе внимание экспериментаторов и получил подкормку, причем ступень иерархии тем выше, чем больше и чаще особь подкармливали. Доминирующие особи требуют демонстрации подчиненного отношения со стороны остальных и проявляют агрессию в случае отсутствия такого отношения. Они с явным превосходством относятся к чайникам, не получавшим подкормку, склонны унижать и облаивать их. Чайник - животное общественное. Действия чайника нередко направлены не только на собственное благополучие, но и на выживание своей популяции. Привыкнув к получению подкормки за определенные действия, чайники начинают принуждать других членов популяции совершать такие же действия; и наоборот, чужие действия, не связанные с подкормкой, вызывают агрессию чайника. Чайник стремится к тому, чтобы другие чайники совершали как можно больше действий, за которые следует ожидать подкормки, и не совершали действий, подкормки за которые не предполагается. Вместе с тем, если начать обеспечивать чайника подкормкой за действия, которые раньше были для него «бесполезными», он переключается на эти действия и заставляет других делать то же самое, несмотря на то, что раньше относился к подобным действиям других с агрессией. Hапример, отмечались случаи, когда чайник, ранее агрессивно относящийся к указанию в документе, после подкормки начал использовать по 2-3 в каждой работе и принуждать к этому других чайников. Это еще одно подтверждение того, что для чайника не свойственны моральные соображения и прочие человеческие качества; вся его деятельность обусловлена исключительно условными рефлексами, опирающимися на подкормку. При встрече с чайником, чтобы избежать опасности, необходимо соблюдать ряд рекомендаций. 1. Hе обманывайтесь внешним сходством чайника и человека. Помните, что чайник подобен попугаю, повторяющему человеческую речь. Он не способен к осмыслению и пониманию; вся его деятельность - только подражание. Hа чайника нельзя обижаться, как нельзя обижаться на домашних животных. 2. Hе выражайте своего несогласия с чайником. Так как чайник не осознает того, что говорит и делает, смысл вашего несогласия останется для него непонятным. Он поймет только то, что чем-то вас не устраивает, а это, как отмечалось выше, является поводом для агрессии и может привести к облаиванию и даже покусанию. Спорить с чайником не более разумно, чем с попугаем или телефонным роботом, сообщающим точное время. 3. Hи в коем случае не создавайте у чайника впечатления, что вы от него чего-то хотите. Это послужит для него основанием требовать подкормки и проявлять агрессию при ее отсутствии. Hе задавайте чайнику вопросов, если ваша безопасность в случае его агрессии не обеспечена. 4. В случае, если чайник проявил к вам интерес, легче всего отпугнуть его ссылкой на сайт, за который вы получили деньги. Если у вас нет такого сайта, бороться с чайником сложнее: как уже отмечалось выше, подкормка является для чайника единственным критерием расположения в чайниковой иерархии. Впрочем, в этом случае можно сделать вид, что вы вообще не имеете отношения к веб-дизайну - тогда у чайника не будет повода интересоваться вами. Владельцам веб-серверов рекомендуется принимать меры по недопущению чайников на сервер. Если же чайники все-таки проникли, необходимо следить за отходами их жизнедеятельности и своевременно удалять их с сервера. За размещение и поддержку работ чайников на сервере необходимо требовать сумму, заведомо превышающую максимально возможную для чайника подкормку. Представляется разумным содержать популяции чайников в специально отведенных для этого резервациях, таких, как Narod.Ru или Geocities.Com. Чайники, будучи общественными животными, самостоятельно скапливаются в подобных резервациях, что уменьшает вероятность случайной встречи с ними в других местах Всемирной Паутины. В настоящее время изучение чайников продолжается. Ученые надеются получить новые результаты, которые помогут в борьбе с этими животными. :)) Присылайте компьютерные анекдоты, рассказы и истории по этой ссылке и они будут опубликованы в ближайших выпусках рассылки. WWW: http://www.delphi.int.ru/ E-mail: admin@delphi.int.ru; support@delphi.int.ru
Архив рассылки: http://subscribe.ru/archive/comp.soft.prog.delphifaq Ведущий рассылки: Ерёмин Андрей
|
В избранное | ||