IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> База вопросов
сообщение
Сообщение #1


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Мне нужно сделать тест. Базу вопросов хочу хранить как file of record. Проблема заключается в том, что в тесте должны быть картинки. Хотел сделать как поле записи. Но вот проблема: в файл не записывается ни поле :TImage ни :TPicture ни даже :TBitmap.
Как это можно осуществить?

Сообщение отредактировано: sheka -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Цитата
Как это можно осуществить?
По разному можно. Например, выбросить из головы желание заниматься глупостями и изобретать базу самостоятельно. Берешь любую настоящую базу данных (тот же MSAccess) и делаешь с ней все, что хочешь...

Можно забросить содержимое картинки в TMemoryStream, и из него уже записать в файл. Но тут возникает вопрос: а сколько ты места отвел для хранения картинки в том поле, где она будет храниться? А если не поместится - что делать будешь?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Мне это надо в Дельфях...

Можете набросать пример?
type
tq=record
p:tbitmap;
end;

var
q:tq;
f:file of tq;

begin
//
end;
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата
Мне это надо в Дельфях...
Чего это? У тебя ж файл, который типизированный, не будет прямо в твоем EXE-шнике храниться, правда? Так какая разница, сделаешь ты хранение в MDB, а интерфейс в Дельфи или хранение в своем file of record, и интерфейс в том же Дельфи?

Цитата
type
tq=record
p:tbitmap;
end;

не пойдет. TBitmap - это класс, сохранение которого тебе ничего не даст (ну, сохранил ты в файле адрес того участка, где хранилось изображение, или его палитра, и что? Перезапусти программу, изображения там уже нет, при попытке чтения оттуда в лучшем случае получишь AV)

В общем, хочешь извращений - читай: Сериализация объектов стандартными средствами Delphi и реализуй... Как надоест - скажешь, я помогу тебе организовать хранение в БД.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Цитата
Так какая разница, сделаешь ты хранение в MDB, а интерфейс в Дельфи или хранение в своем file of record, и интерфейс в том же Дельфи?

Я с базами данных вообще никогда не работал. Слышал, что так это можно осуществить, просмотрел книжки мельком, но то что я там заметил - меня особо не обрадовало: составление таблиц, сортировки по параметрам итд.. "На готовенькое" не попал. Думал, через файлы легче будет.
Цитата
не пойдет. TBitmap - это класс, сохранение которого тебе ничего не даст (ну, сохранил ты в файле адрес того участка, где хранилось изображение, или его палитра, и что? Перезапусти программу, изображения там уже нет, при попытке чтения оттуда в лучшем случае получишь AV)
Теперь я понял, почему вот эта программа:

var
q,w:TBitmap;
f:file of TBitmap;
begin
assignfile(f,'in');
{ rewrite(f);
q:=TBitmap.Create;
q.LoadFromFile('1.bmp');
write(f,q);
closefile(f);}
reset(f);
read(f,w);
closefile(f);
form1.Image1.Picture.Bitmap:=w;
end;

При втором запуске (и закомментированом коде) выдает ошибку, а если раскомментировать, то все нормально smile.gif
Что такое АV?
Как надоест - скажешь, я помогу тебе организовать хранение в БД.
Допустим уже надоело. Прочитать - прочитаю, но времени катастрофически нет... в идеале програмку надо было еще месяц назад сдать... а так где-то неделька осталась...

Добавлено через 2 мин.
Помогите) С чего надо начинать?

Как бы отмазаться я смогу - тест из текстового файла есть, но ведь это же не то.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата
то что я там заметил - меня особо не обрадовало: составление таблиц, сортировки по параметрам итд.. "На готовенькое" не попал.
blink.gif А на что ты рассчитывал попасть? На готовую программу? smile.gif

Чего там делать? Открываешь MS Access, создаешь одну таблицу, содержащую как минимум одно поле типа OLEObject - я назвал его image - (в нем будет храниться изображение. Если тебе надо еще что-то - создавай сразу и все остальное).

Все поля, которые нужны - создал? Сохраняешь БД, и выходишь из Access-а, вся дальнейшая работа - из Дельфи. Сначала надо связать базу с твоей программой. Для этого на форму положим компонент TADOConnection (из раздела DbGo, у меня Д2009, поэтому, извини, все дальнейшие места расположения компонентов я буду приводить именно из этой версии), компонент TADOTable (тоже DbGo), и TDataSource (из Data Access)...

Вот тут лежит Видео, около 2.5 Мб, показывающее, как и в какой последовательности надо подключать базу к проекту на Дельфи (это было давно сделано, почти 2 года назад, просто сейчас оно оказалось нужно smile.gif )

Подключил все, DBGrid показывает пустые ячейки? Прекрасно... Теперь можно их заполнять. Чтоб занести текст - можно прямо использовать DBGrid (т.е., прямо в нем и печатать). Картинки - да пожалуйста:

// 1. Из TImage в текущую запись БД:
procedure TForm1.Button1Click(Sender: TObject);
var memStr: TMemoryStream;
begin
memStr := TMemoryStream.Create;
try
Image1.Picture.Graphic.SaveToStream(memStr);
memStr.Seek(0, soFromBeginning);
DBGrid1.DataSource.DataSet.Edit;
TBlobField(DBGrid1.DataSource.DataSet.FieldByName('image')).LoadFromStream(memStr);
DBGrid1.DataSource.DataSet.Post;
finally
memStr.Free;
end;
end;

// 2. Из текущей записи БД назад в TImage - легко:
procedure TForm1.Button2Click(Sender: TObject);
var
bStream: TADOBlobStream;
bm: TBitmap;
begin
if not DBGrid1.DataSource.DataSet.FieldByName('image').IsNull then
begin
bStream := TADOBlobStream.Create(TBlobField(DBGrid1.DataSource.DataSet.FieldByName('image')), bmRead);
try
bm := TBitmap.Create;
bm.LoadFromStream(bStream);
Image2.Picture.Bitmap.Assign(bm); // Это я для теста гружу в ДРУГОЙ Image
bm.Free;
finally
bStream.Free;
end;
end;
end;


Ну, для начала тебе этого должно хватить... smile.gif

Цитата
Что такое АV?
Это Access Violation - запрет доступа.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


sheka, база данных - это правильное решение, с ним разберись обязательно. Но если программа нужна срочно, то не вижу смысла вообще хранить изображения в каких-то своих форматах. Создай директорию и храни изображения там. Можешь изменить расширения файлов, чтобы никто не догадался =). А в записи отведи место только под имя файла.


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Цитата
А на что ты рассчитывал попасть? На готовую программу?
Ну как минимум на пример smile.gif
Archon, именно в таком виде у меня есть.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


а можно вопрос? smile.gif
как организовать фильтрацию данных? как можно тут использовать запросы?
например, хочу найти записи, значение поля 'fio' равно 'Иванов'. записей может быть несколько

Сообщение отредактировано: Client -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Фильтруй, кто тебе запрещает?

procedure TForm1.Button3Click(Sender: TObject);
var s: string;
begin
s := 'Иванов';
ADOTable1.Filtered := False;
ADOTable1.Filter := '[fio] = ' + QuotedStr(s);
ADOTable1.Filtered := True;
end;
Оставит тебе только Ивановых.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


спасибо
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


что-то сразу не заметил
QuotedStr(s);
Что она делает? тыкнул ctrl+mouse и нашел описание функции
function QuotedStr(const S: string): string;
var
I: Integer;
begin
Result := S;
for I := Length(Result) downto 1 do
if Result[I] = '''' then Insert('''', Result, I);
Result := '''' + Result + '''';
end;
сделал эксперимент
procedure TForm2.Button2Click(Sender: TObject);
begin
Button2.Caption:='''';
end;
В итоге есть только одн апостроф. Получается, что <''''> это и есть апостроф в строке?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






Цитата
Что она делает?
Ничего особенного. Просто преобразует входную строку так, что она на выходе "обернута" апострофами. Кстати, в основном - именно для работ с БД, где требуется строковые параметры запросов заключать в апострофы...

Цитата
Получается, что <''''> это и есть апостроф в строке?
Да, внешние апострофы - это признак строки, а внутренние два - это один апостроф, который строка и содержит... Дублирование необходимо для того, чтобы не завершать строку:
Button2.Caption := 'test of 's: error'; // Первый же одиночный апостроф строку "сломал"


 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


хитро... раньше вставлял апостроф с помощью chr(), а теперь буду знать как лучше smile.gif smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


А как узнать индекс выделенной записи в DBGrid?
Есть ли для этого какая-то функция или надо в цикле проверять selected ?


Добавлено через 1 мин.
Что такое TQuery?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Цитата
А как узнать индекс выделенной записи в DBGrid?
А можно глупый вопрос? "А зачем?"

Нет такой функции, и не рекомендую я тебе ее писать... Ибо DBGrid может находиться в режиме фильтрации, ты найдешь индекс выделенной строки, потом тебе захочется что-то с ним сделать, а фильтр отменится или изменится, вся индексация летит к чертям, что дальше?

Обходной путь, конечно, есть. В классе TDBGrid есть свойство Row, но оно скрыто от посторонних глаз. Можно его открыть. Добавляешь
type
TDBGrid = class(DBGrids.TDBGrid)
public // Теперь Row считается общим членом класса
property Row;
end;
перед описанием класса формы, и потом обращаешься к свойству Row там, где нужно получить номер текущей записи ДБГрида. Но учти, разработчики VCL совсем не просто так ее скрыли от посторонних "шаловливых ручек". Некоторые причины я тебе уже привел.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Цитата
"А зачем?"
Например, удалить выделенную запись из базы.

Также интересует еще вопрос с картинкой: я нашел как ее можно показывать в самом DBGridе, по моему там было с помощью отрисовки Bitmapа на canvasе клетки, но в таком случае возникает вопрос с подгонкой размера картинки под размер клетки. Поэтому думал сделать так: если выделена запись, то вывести ее значение поля OLE в Image, который где-то бы на форме находился.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






А для этого ни разу не надо знать номер строки... Любая операция в Гриде производится с текущей строкой. Для ее удаления можно применить:
  DBGrid1.DataSource.DataSet.Delete;


Цитата
Поэтому думал сделать так: если выделена запись, то вывести ее значение поля OLE в Image, который где-то бы на форме находился.
Правильно думал... Я приводил код отображения картинки из БД в TImage... Если его повесить на событие DBGrid->DataSource->OnDataChange, это будет выполнять поставленную задачу:
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
var
bStream: TADOBlobStream;
bm: TBitmap;
begin
if not DBGrid1.DataSource.DataSet.FieldByName('image').IsNull then
begin
bStream := TADOBlobStream.Create(TBlobField(DBGrid1.DataSource.DataSet.FieldByName('image')), bmRead);
try
bm := TBitmap.Create;
bm.LoadFromStream(bStream);
Image2.Picture.Bitmap.Assign(bm);
bm.Free;
finally
bStream.Free;
end;
end
else Image2.Picture := nil; // поле image пустое... Очищаем
end;


Это тебе не самописная база, где все пришлось бы делать вручную, и отслеживать текущую запись, и ловить момент перехода по списку записей... В ADO уже все есть...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Опять столкнулся с проблемой. Точнее с -ами)))

У меня должен в базе храниться достаточно длинный текст (где-то 1-3 предложения), а он целиком не помещается в одну строку(MSAccess на длину ругается, но это ничего страшного, можна обойтись и этой длиной. проблема в неудобности обозрения информации) . Вычитал, что стандартно многострочным поле ДБГрида быть не может. Мои варианты решений проблемы:
1) т.к. времени очень мало - забить на создание редактора базы и пользоваться MSAccess в этих целях. Но как тогда загрузить картинку через него? Если ее загружаешь( или просто из папки перетаскиваешь в поле ОЛЕ, или рисуешь встроеным редактором), то делфи выдает ошибку при считывании этого поля.
2) использовать поле МЕМО, вывод которого ДБГрид тоже не поддерживает. Т.е. его надо привязать к объекту мемо(тому который на форму кинуть можно).

из 2) появляется еще один вопрос: как считывать информацию из полей ДБГрида? (тоже как-то через поток?):
а) просто текстового поля
б) поля МЕМО - для реализации 2-го пункта.

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Гость






Цитата
а он целиком не помещается в одну строку(MSAccess на длину ругается
blink.gif Поле типа Memo (описанное как Memo в Access-е) способно хранить до 64К текста... Ничего себе у тебя предложения...

Цитата
использовать поле МЕМО, вывод которого ДБГрид тоже не поддерживает. Т.е. его надо привязать к объекту мемо(тому который на форму кинуть можно).
Это твои фантазии... Точно так же, как и в любой другой контрол, в ячейку DBGrid-а можно вставить TMemo. Подробнее - здесь: НеОбычный TDBGrid

Итого, у тебя есть варианты:
1. Положить на форму TMemo и точно так же, как ты из базы вытягиваешь картинку в лежащий на форме TImage, в этот самый Memo сбрасывать текст из соотв. поля текущей записи. Это обычный текст, кстати... Просто
Memo1.Text := DBGrid1.DataSource.DataSet.FieldByName('memo_field').AsString;

2. (предпочтительно) Воспользоваться TDBMemo, связать его с нужным полем в таблице, и за тебя это будет делать сам компонент (кстати, я прошляпил, надо было тебе и про TDBImage сразу сказать, точно так же - связал с полем и при перемещении по DBGrid-у изображение изменяется автоматически...)
3. Вставить Memo внутрь DBGrid-а.

Выбирай...

Какая у тебя Дельфи, скажи заодно, чтоб я хоть примерно знал, что есть в арсенале, а чего нету...
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 24.04.2024 15:54
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name