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

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным. В описании темы указываем язык!!!

 
 Ответить  Открыть новую тему 
> Помогите с подгрузкой изображения в БД. С++, Помогите с подгрузкой изображения в БД. С++
alecsandr
сообщение 5.06.2011 12:34
Сообщение #1


Пионер
**

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

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


У меня есть программа, АРМ администратора компьютерного магазина, вроде когда я беру изображения из БД все нормально картинка отображается в DBImagе, но когда жму кнопку "ДОБАВИТЬ" (Добавиьт данные в таблицу) он выбивает ошибку поэтому даже проверить не могу работоспособность добавления. Помогите пожалуйто с добавлением буду очень благодарен. В архиве прикрепленном снизу вся прога с БД. ВСЕ РАЗАРХИВИРУЙТЕ В ОДНУ ПАПКУ

Сообщение отредактировано: alecsandr - 5.06.2011 12:48


Прикрепленные файлы
Прикрепленный файл  P2.zip ( 1.23 мегабайт ) Кол-во скачиваний: 225
Прикрепленный файл  P1.zip ( 1.72 мегабайт ) Кол-во скачиваний: 216
Прикрепленный файл  P3.zip ( 147.15 килобайт ) Кол-во скачиваний: 203
Прикрепленный файл  P4.zip ( 741.19 килобайт ) Кол-во скачиваний: 217
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 5.06.2011 12:46
Сообщение #2


a.k.a. volvo877
*****

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

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


Цитата
В архиве прикрепленном снизу вся прога с БД
Ну, и где? Архив, говорю, снизу чего прикреплен? Под монитором посмотрел - нету...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
alecsandr
сообщение 5.06.2011 12:49
Сообщение #3


Пионер
**

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

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


Цитата(IUnknown @ 5.06.2011 12:46) *

Ну, и где? Архив, говорю, снизу чего прикреплен? Под монитором посмотрел - нету...

иЗВИНИ ОН НЕ ОТПРАВИЛСЯ))
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 5.06.2011 14:19
Сообщение #4


a.k.a. volvo877
*****

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

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


Ну, во-первых, вот это:
if (Form2->DataSource1->DataSet->FieldByName("Photo")==NULL)
- неправильно. У тебя никогда не поймается таким образом пустая строка. Ловить пустоту надо вот так:
if ((Form2->DataSource1->DataSet->FieldByName("Photo")->AsString).IsEmpty())


А во-вторых: не надо при добавлении новой записи в базу записывать полный путь к файлу. Достаточно только имени. Иначе сам подумай, что будет пытаться открыть LoadFromFile вот тут: LoadFromFile("photo\\" + strphoto), если в strphoto УЖЕ записан полный путь? Нехорошо, вылет программы обеспечен.

Вот так попробуй:
  if ((Form2->DataSource1->DataSet->FieldByName("Photo")->AsString).IsEmpty()) // Изменения здесь
{
Form2->ADOQuery1->Edit();
Form2->DataSource1->DataSet->FieldValues["Photo"]= "none.jpg"; // и здесь
}
strphoto = Form2->DataSource1->DataSet->FieldValues["Photo"];
Form2->DataSource1->DataSet->Post();
Form2->DBImage1->Stretch=true;
Form2->DBImage1->Picture->LoadFromFile("photo\\" + strphoto);

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
alecsandr
сообщение 5.06.2011 16:14
Сообщение #5


Пионер
**

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

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


Цитата(IUnknown @ 5.06.2011 14:19) *

Ну, во-первых, вот это:
if (Form2->DataSource1->DataSet->FieldByName("Photo")==NULL)
- неправильно. У тебя никогда не поймается таким образом пустая строка. Ловить пустоту надо вот так:
if ((Form2->DataSource1->DataSet->FieldByName("Photo")->AsString).IsEmpty())


А во-вторых: не надо при добавлении новой записи в базу записывать полный путь к файлу. Достаточно только имени. Иначе сам подумай, что будет пытаться открыть LoadFromFile вот тут: LoadFromFile("photo\\" + strphoto), если в strphoto УЖЕ записан полный путь? Нехорошо, вылет программы обеспечен.

Вот так попробуй:
  if ((Form2->DataSource1->DataSet->FieldByName("Photo")->AsString).IsEmpty()) // Изменения здесь
{
Form2->ADOQuery1->Edit();
Form2->DataSource1->DataSet->FieldValues["Photo"]= "none.jpg"; // и здесь
}
strphoto = Form2->DataSource1->DataSet->FieldValues["Photo"];
Form2->DataSource1->DataSet->Post();
Form2->DBImage1->Stretch=true;
Form2->DBImage1->Picture->LoadFromFile("photo\\" + strphoto);



Блин он все ровно не пашет, пишет что не найден none.jpg
и останавливается на этой строчке
 Form2->DBImage1->Picture->LoadFromFile("photo\\" + strphoto);
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 5.06.2011 16:30
Сообщение #6


a.k.a. volvo877
*****

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

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


Цитата
Блин он все ровно не пашет, пишет что не найден none.jpg
и останавливается на этой строчке
Да что ж такое?

Прикрепленное изображение
Опять у меня все не так, как нужно? Не останавливается, грузит форму с пустыми полями, чтоб их можно было обновить. Что ж я все-время не так делаю, а? Сколько раз повторять, я ПРОВЕРЯЮ код, который выкладываю. Если не работает - кода просто НЕТ. Так что ищи ошибку у себя...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
alecsandr
сообщение 5.06.2011 18:43
Сообщение #7


Пионер
**

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

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


Цитата(IUnknown @ 5.06.2011 16:30) *

Да что ж такое?

Прикрепленное изображение
Опять у меня все не так, как нужно? Не останавливается, грузит форму с пустыми полями, чтоб их можно было обновить. Что ж я все-время не так делаю, а? Сколько раз повторять, я ПРОВЕРЯЮ код, который выкладываю. Если не работает - кода просто НЕТ. Так что ищи ошибку у себя...



Он форму открывает, и у меня но когда я жму применить выбивает ошибку((


Добавлено через 8 мин.
У меня вот так вылаживаю фотки пошагово


Эскизы прикрепленных изображений
Прикрепленное изображение Прикрепленное изображение Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 5.06.2011 19:53
Сообщение #8


a.k.a. volvo877
*****

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

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


Так... Ну, у тебя весь бардак - из-за того, что при нажатии на кнопку "Обзор" ты выбираешь файл, это меняет рабочую папку, и, соответственно, при дальнейших попытках открыть файл у тебя ничего не получается: папка изменилась, абсолютный путь - другой, программа аварийно завершается. После того, как бала нажата кнопка "Обзор", восстанавливай текущую папку (через SetCurrentDir), причем не только тогда, когда Execute завершилась удачно, а в любом случае. А fname присваивай не полное имя файла, а только ExtractFileName(Form3->OpenDialog1->FileName)... Тогда у тебя в любое время
а) будет правильная текущая папка;
б) будет правильное короткое имя файла изображения.

Разумеется, если ты хочешь подгружать изображения и из других папок - то это все надо делать по-другому, тогда надо вычислять относительный путь к файлу JPG от текущей папки (той, где лежит EXE-шник)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
alecsandr
сообщение 5.06.2011 20:01
Сообщение #9


Пионер
**

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

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


Цитата(IUnknown @ 5.06.2011 19:53) *

Так... Ну, у тебя весь бардак - из-за того, что при нажатии на кнопку "Обзор" ты выбираешь файл, это меняет рабочую папку, и, соответственно, при дальнейших попытках открыть файл у тебя ничего не получается: папка изменилась, абсолютный путь - другой, программа аварийно завершается. После того, как бала нажата кнопка "Обзор", восстанавливай текущую папку (через SetCurrentDir), причем не только тогда, когда Execute завершилась удачно, а в любом случае. А fname присваивай не полное имя файла, а только ExtractFileName(Form3->OpenDialog1->FileName)... Тогда у тебя в любое время
а) будет правильная текущая папка;
б) будет правильное короткое имя файла изображения.

Разумеется, если ты хочешь подгружать изображения и из других папок - то это все надо делать по-другому, тогда надо вычислять относительный путь к файлу JPG от текущей папки (той, где лежит EXE-шник)

Извини что надоедаю, ном ог бы не много подробнее)), а то просто не понял(((( особенно про setcurrentdir, просто такого даже не учили((
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 5.06.2011 20:55
Сообщение #10


a.k.a. volvo877
*****

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

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


Прежде, чем с этим заморачиваться - ты сделай, чтобы у тебя к моменту открытия Form3 набор данных был уже открыт, те DBEdit-ы, которые лежат на форме, чтоб хоть как-то функционировали. А то смысл такой формы в чем? Не назначено DBEdit-ам ни RecordSet-а, ни имени поля в базе. Открылась форма, пытаешься ввести что-то - "а фиг тебе, я ни на что не реагирую". В топку такую форму, зачем она нужна, если не связана с базой, и не позволяет менять данные на лету? Или что, я должен в открытой форме выбрать название изображения, вслепую ее закрыть (а кнопочка Отмена не работает, закрывать приходится крестиком), а потом прямо в DBGrid-е изменять данные? Меня такое приложение мало интересует, я им заниматься не буду.

Второе: ты сравни свой скриншот с моим. Почему у тебя форма выглядит как положено, а у меня - нет? Это что, из серии "на мониторах больше 17 инч - не запускать, и только для Windows 7"? Приложение идет тем же лесом, что и из-за неадекватной формы. Исправляй работоспособность Form3, и внешний вид, и присоединяй проект. Только я тебя прошу: не надо мне твои obj-файлы и файлы истории. Убери все лишнее, зачем мегабайтные tds-файлы туда сюда перекачивать? Они мне на фиг не сдались, у меня все равно Builder 2009. Только MDB, CPP, H и BPR, все остальное любой откомпилирует сам...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
alecsandr
сообщение 5.06.2011 21:44
Сообщение #11


Пионер
**

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

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


Цитата(IUnknown @ 5.06.2011 20:55) *

Прежде, чем с этим заморачиваться - ты сделай, чтобы у тебя к моменту открытия Form3 набор данных был уже открыт, те DBEdit-ы, которые лежат на форме, чтоб хоть как-то функционировали. А то смысл такой формы в чем? Не назначено DBEdit-ам ни RecordSet-а, ни имени поля в базе. Открылась форма, пытаешься ввести что-то - "а фиг тебе, я ни на что не реагирую". В топку такую форму, зачем она нужна, если не связана с базой, и не позволяет менять данные на лету? Или что, я должен в открытой форме выбрать название изображения, вслепую ее закрыть (а кнопочка Отмена не работает, закрывать приходится крестиком), а потом прямо в DBGrid-е изменять данные? Меня такое приложение мало интересует, я им заниматься не буду.

Второе: ты сравни свой скриншот с моим. Почему у тебя форма выглядит как положено, а у меня - нет? Это что, из серии "на мониторах больше 17 инч - не запускать, и только для Windows 7"? Приложение идет тем же лесом, что и из-за неадекватной формы. Исправляй работоспособность Form3, и внешний вид, и присоединяй проект. Только я тебя прошу: не надо мне твои obj-файлы и файлы истории. Убери все лишнее, зачем мегабайтные tds-файлы туда сюда перекачивать? Они мне на фиг не сдались, у меня все равно Builder 2009. Только MDB, CPP, H и BPR, все остальное любой откомпилирует сам...


Вот сдесь можно изменять DBEDIt, они уже связаны с базой, клавиша отмена работает


Прикрепленные файлы
Прикрепленный файл  1.rar ( 497.23 килобайт ) Кол-во скачиваний: 207
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 6.06.2011 9:01
Сообщение #12


a.k.a. volvo877
*****

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

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


DFM - файлы добавь в проект, а то восстанавливать форму не очень хочется вручную.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
alecsandr
сообщение 6.06.2011 9:03
Сообщение #13


Пионер
**

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

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


Цитата(IUnknown @ 6.06.2011 9:01) *

DFM - файлы добавь в проект, а то восстанавливать форму не очень хочется вручную.


нУ вроде скинул


Прикрепленные файлы
Прикрепленный файл  1.rar ( 501.72 килобайт ) Кол-во скачиваний: 202
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
IUnknown
сообщение 6.06.2011 9:51
Сообщение #14


a.k.a. volvo877
*****

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

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


Значит, смотри, что я сделал:

1) на Form3 вместо Edit1 добавил DBEdit4, связал его с полем Photo набора данных. Естественно, что в обработчике кнопки "Обзор" я заношу имя файла не в Edit1, а в DBEdit4.
2) с обработкой "Применить" у тебя - полный бардак. Я сделал так:
void __fastcall TForm3::Button2Click(TObject *Sender)
{
// Ничего заносить в поле Photo уже не надо, это делается автоматически
//Form2->DataSource1->DataSet->FieldValues["Photo"];// присваиваем имя фотографии товара

Form2->ADOQuery1->Edit(); // Тебе не нужно ДОБАВЛЯТЬ запись, достаточно ее ОБНОВИТЬ
Form2->DataSource1->DataSet->Post();
Form2->DBImage1->Stretch=true;
// Вот так я добиваюсь того, чтобы изображение читалось из текущей папки + /photo ВСЕГДА
Form2->DBImage1->Picture->LoadFromFile(ExtractFilePath(Application->ExeName) + "photo\\" + fname);

// Вот этого тоже делать не надо, не оставляй набор данных в открытом состоянии,
// не ты один можешь работать с базой, это будет мешать остальным...
// при выделении товара показывать информацию о нем
// Form2->ADOQuery1->Edit();
Form3->Close();
}


Точно так же, как и тут, я переделал строку в LoadPhoto() :
 Form2->DBImage1->Picture->LoadFromFile(ExtractFilePath(Application->ExeName) + "photo\\" + strphoto);
// при выделении товара показывать информацию о нем
, теперь все прекрасно добавляется и ничего никуда не вылетает.

Теперь еще кое-что:
1) у тебя программа не завершается корректно, остается висеть в процессах. При отладке работе из Билдера это видно, просто снимаешь ее с выполнения через Ctrl+F2 и все. А вот если запустить программу из проводника - то потом ее приходится снимать из диспетчера задач. Ищи причину.
2) утечка памяти. Ты выделяешь
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int i;
char *k=new char[5]; // <--- Вот тут
память?
Где освобождение? CodeGuard тут же поднимает тревогу. Кстати, то, что ты делаешь - вообще неправильно. Как минимум потому, что выделять память надо на один символ больше, чем будешь использовать, для завершающего нуля. Ты этого не сделал. Исправляй эти недочеты тоже...

Добавлено через 12 мин.
Да, кстати, еще одно... Весь вот этот ужас:

Цитата
if (Form2->ComboBox1->ItemIndex==0)
{
Form2->ADOQuery1->SQL->Add("Select * FROM Акустика");
Form2->ADOQuery1->SQL->Add("WHERE (Наименование LIKE'%"+Edit1->Text+"%') ORDER by Наименование ASC");
Form2->ADOQuery1->Open();
Form2->DataSource1->DataSet=Form2->ADOQuery1;
// LoadPhoto();
}
else
if (Form2->ComboBox1->ItemIndex==1)
{
Form2->ADOQuery1->SQL->Add("Select * FROM Материнки");
Form2->ADOQuery1->SQL->Add("WHERE (Наименование LIKE'%"+Edit1->Text+"%') ORDER by Наименование ASC");
Form2->ADOQuery1->Open();
Form2->DataSource1->DataSet=Form2->ADOQuery1;
//LoadPhoto();
}
else ...
(и так далее еще 8 раз) - очень просто укладывается в 4 строки, независимо от количества таблиц в базе:
	Form2->ADOQuery1->SQL->Add("Select * FROM " + ComboBox1->Text);
Form2->ADOQuery1->SQL->Add("WHERE (Наименование LIKE'%"+Edit1->Text+"%') ORDER by Наименование ASC");
Form2->ADOQuery1->Open();
Form2->DataSource1->DataSet=Form2->ADOQuery1;
Угу? Главное, чтобы текст в комбобоксе совпадал с названием таблицы.

То же самое касается и десяти кнопок для выбора показываемой таблицы. Достаточно сделать один обработчик, работающий с Caption-ом Sender-а, и назначить его всем кнопкам. Не нужен тут Copy+Paste...

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


Пионер
**

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

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


Цитата(IUnknown @ 6.06.2011 9:51) *

Значит, смотри, что я сделал:

1) на Form3 вместо Edit1 добавил DBEdit4, связал его с полем Photo набора данных. Естественно, что в обработчике кнопки "Обзор" я заношу имя файла не в Edit1, а в DBEdit4.
2) с обработкой "Применить" у тебя - полный бардак. Я сделал так:
void __fastcall TForm3::Button2Click(TObject *Sender)
{
// Ничего заносить в поле Photo уже не надо, это делается автоматически
//Form2->DataSource1->DataSet->FieldValues["Photo"];// присваиваем имя фотографии товара

Form2->ADOQuery1->Edit(); // Тебе не нужно ДОБАВЛЯТЬ запись, достаточно ее ОБНОВИТЬ
Form2->DataSource1->DataSet->Post();
Form2->DBImage1->Stretch=true;
// Вот так я добиваюсь того, чтобы изображение читалось из текущей папки + /photo ВСЕГДА
Form2->DBImage1->Picture->LoadFromFile(ExtractFilePath(Application->ExeName) + "photo\\" + fname);

// Вот этого тоже делать не надо, не оставляй набор данных в открытом состоянии,
// не ты один можешь работать с базой, это будет мешать остальным...
// при выделении товара показывать информацию о нем
// Form2->ADOQuery1->Edit();
Form3->Close();
}


Точно так же, как и тут, я переделал строку в LoadPhoto() :
 Form2->DBImage1->Picture->LoadFromFile(ExtractFilePath(Application->ExeName) + "photo\\" + strphoto);
// при выделении товара показывать информацию о нем
, теперь все прекрасно добавляется и ничего никуда не вылетает.

Теперь еще кое-что:
1) у тебя программа не завершается корректно, остается висеть в процессах. При отладке работе из Билдера это видно, просто снимаешь ее с выполнения через Ctrl+F2 и все. А вот если запустить программу из проводника - то потом ее приходится снимать из диспетчера задач. Ищи причину.
2) утечка памяти. Ты выделяешь
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int i;
char *k=new char[5]; // <--- Вот тут
память?
Где освобождение? CodeGuard тут же поднимает тревогу. Кстати, то, что ты делаешь - вообще неправильно. Как минимум потому, что выделять память надо на один символ больше, чем будешь использовать, для завершающего нуля. Ты этого не сделал. Исправляй эти недочеты тоже...

Добавлено через 12 мин.
Да, кстати, еще одно... Весь вот этот ужас:

(и так далее еще 8 раз) - очень просто укладывается в 4 строки, независимо от количества таблиц в базе:
	Form2->ADOQuery1->SQL->Add("Select * FROM " + ComboBox1->Text);
Form2->ADOQuery1->SQL->Add("WHERE (Наименование LIKE'%"+Edit1->Text+"%') ORDER by Наименование ASC");
Form2->ADOQuery1->Open();
Form2->DataSource1->DataSet=Form2->ADOQuery1;
Угу? Главное, чтобы текст в комбобоксе совпадал с названием таблицы.

То же самое касается и десяти кнопок для выбора показываемой таблицы. Достаточно сделать один обработчик, работающий с Caption-ом Sender-а, и назначить его всем кнопкам. Не нужен тут Copy+Paste...



Спасибо огромное очень сильно помог)) Премного благодарен тебе!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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

 



- Текстовая версия 28.03.2024 18:20
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"