TDBLookupComboBox: Странное поведение [Решено]

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

TDBLookupComboBox: Странное поведение [Решено]

Сообщение Unvictis » 05.04.2016 12:37:15

Здравствуйте, товарищи! Пишу простейшую оболочку к базе данных для склада своей мастерской на СУБД SQLite 3 (Lazarus 1.4.4, SQLite 3.8.10.2, TSQLite3Dataset).

Изображение

Моя БД содержит всего четыре таблицы:
  • Parts - Основная таблица, в ней хранятся данные о комплектующих, и внешние ключи на остальные три таблицы
  • Types - Типы комплектующих (Процессор, видеокарта и т. д.)
  • Conditions - Состояния этих комплектующих (Новые, б/у, на детали, и т. д.)
  • Storages - Хранилища (по-русски, пронумерованные коробки и полки) где эти детали лежат

Для подключения к БД использую 4 штуки TSQLite3Dataset идущий в стандартной поставке Lazarus'а и четыре TDataSource для связи с визуальными компонентами - их я вынес в отдельный Data Module.

Теперь суть вопроса: При добавлении в любую из трёх таблиц справочников (Types, Conditions, Storages) новой записи, и попытке вслед за этим добавить запись в основную таблицу Parts (например, я сначала добавил в БД в таблицу Storages новое место хранения, а затем сразу же хочу добавить деталь в таблицу Parts) компонент TDBLookupComboBox связанный с изменённой таблицей во первых сразу-же отображает текст новой записи, а самое главное она не вставляет в поле указанное в DataField внешний ключ новой записи. Если ничего не добавлять в другие таблицы, а сразу же добавить деталь в таблицу Parts - никаких проблем. Всё также работает если добавить например данные о складе или состоянии в соответствующие таблицы, перезапустить программу а после добавлять данные в таблицу Parts. И на сколько я понял, при удалении или изменении данных, такого эффекта не наблюдается. Пробовал Перед отображением формы добавления новой записи в таблицу Parts выполнять в разной последовательности методы Refresh, RefetchData всех компонентов TSQLite3Dataset, метод Refresh компонентов TDBLookupComboBox - ничего не изменилось. Запись данных в БД при вставке новых записей в смежные таблицы происходит однозначно - открывал БД в SQLiteStudio 3.0.7 - запись появляется. Где-то читал, что нужно закрыть и заново открыть датасеты, но лично мне кажется это не логичным влечёт кучу дополнительных проблем, в виде не открытого вовремя датасета..

Вот иллюстрация для наглядности.

Изображение

Чем вызвано подобное поведение, и как решить данную проблему. Совсем отчаялся разобраться. Всем заранее большое спасибо! Простите за много букв.
Последний раз редактировалось Unvictis 20.04.2016 09:08:50, всего редактировалось 1 раз.
Аватара пользователя
Unvictis
новенький
 
Сообщения: 48
Зарегистрирован: 17.07.2015 18:59:12
Откуда: Kokshetau, Kazakshtan

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение DYUMON » 05.04.2016 14:45:55

applyupdates не делаешь что ли где то?
Аватара пользователя
DYUMON
постоялец
 
Сообщения: 234
Зарегистрирован: 11.03.2009 13:32:54

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение Unvictis » 05.04.2016 15:04:42

DYUMON писал(а):applyupdates не делаешь что ли где то?

В том то и дело, что делаю сразу же после Post'a. Проблема не в том что данные не добавляются в БД - добавляются, проверял, а в том что TDBLookupCombobox не корректно с ними работает.
Аватара пользователя
Unvictis
новенький
 
Сообщения: 48
Зарегистрирован: 17.07.2015 18:59:12
Откуда: Kokshetau, Kazakshtan

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение vitaly_l » 05.04.2016 15:53:43

Unvictis писал(а):TDBLookupCombobox

Перечитал - понял лишь, что с TDBLookupCombobox, существует некая проблема. Что-то перестаёт отображаться.
Но непонятно в какой именно ситуации?

Если вы переходите от одной строки к другой, всё правильно отображается?
Проблема возникает только после сохранения или всегда?


.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение pupsik » 05.04.2016 20:13:12

Есть 3 варианта:
1. Lazarus 1.4.4 .... Попробуйте обновить.
2. Ошибка вашего кода (логики). Без сорцов не узнать.
3. Сделайте не основываясь на дб компонентах. С одной стороны дольше, зато куда эффективнее.

Третий вариант - визуальные компоненты.

п.с.
Толку от картинок и множества слов не много....
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение Unvictis » 06.04.2016 08:11:27

pupsik писал(а):2. Ошибка вашего кода (логики). Без сорцов не узнать.

Выкладываю исходник: https://drive.google.com/file/d/0B1vV8nYCxqX6WUJvVHZUUDlnNlk/view?usp=sharing (для успешной компиляции требуется библиотека sqlite3.dll и установленный компонент TSQLite3Dataset из ..Lazarus\components\sqlite\sqlite3laz.lpk)

База данных:
Код: Выделить всё
--
-- Файл сгенерирован с помощью SQLiteStudio v3.0.7 в Ср апр 6 10:19:52 2016
--
-- Использованная кодировка текста: windows-1251
--
PRAGMA foreign_keys = off;
BEGIN TRANSACTION;

-- Таблица: Parts
CREATE TABLE Parts (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, Date REAL NOT NULL DEFAULT (CURRENT_TIMESTAMP), Type INTEGER REFERENCES Types (ID) ON DELETE NO ACTION ON UPDATE NO ACTION NOT NULL, Name VARCHAR (50), Serial VARCHAR (50), Condition INTEGER REFERENCES Conditions (ID) ON DELETE NO ACTION ON UPDATE NO ACTION NOT NULL, Storage INTEGER REFERENCES Storages (ID) ON DELETE NO ACTION ON UPDATE NO ACTION NOT NULL, BuyPrice INTEGER DEFAULT (0), SellPrice INTEGER NOT NULL, Selling BOOLEAN NOT NULL, Comment VARCHAR (254));

-- Таблица: Storages
CREATE TABLE Storages (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Name VARCHAR (50) NOT NULL, Comment VARCHAR (254));

-- Таблица: Conditions
CREATE TABLE Conditions (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Name VARCHAR (50) NOT NULL, Comment VARCHAR (254));

-- Таблица: Types
CREATE TABLE Types (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Name VARCHAR (50) NOT NULL, Comment VARCHAR (254));

COMMIT TRANSACTION;
PRAGMA foreign_keys = on;



Добавлено спустя 21 минуту 41 секунду:
pupsik писал(а):1. Lazarus 1.4.4 .... Попробуйте обновить.

Только что скачал последнюю версию Lazarus'a 1.6 SVN 51630, и перекомпилировал проект - результат то-же.
Аватара пользователя
Unvictis
новенький
 
Сообщения: 48
Зарегистрирован: 17.07.2015 18:59:12
Откуда: Kokshetau, Kazakshtan

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение pupsik » 06.04.2016 12:27:53

А так?

п.с.
Возможно баг с копированием. Не тестил в винде. Не уверен что copyfile с кирилицей нормально дружит.
Ну и лазарь поругается малость на некоторые св-ва.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

[Решено] TDBLookupComboBox: Странное поведение (не обновляет

Сообщение Unvictis » 10.04.2016 21:26:33

Большое спасибо всем, кто откликнулся. Разобрался. Я забыл, что значение полю типа AutoInc присваивается только после отправки в БД. И по этому в TDBLookupComboBox'e отображалась запись с пустым ключевым полем.

В общем, решил проблему так: с событии AfterPost компонентов SQLite3Dataset которые привязаны к Lookup-полям просто закрывал, а потом открывал его методами Close и Open (при этом свойство SaveOnClose = True).

Прошу прощение за оффтоп, но может кто подскажет решение ещё одной маленькой проблемы: у меня все датасеты расположены в отдельном датамодуле, а мне бы хотелось в статусбаре главной формы выводить колличество записей которые содержит датасет (тоесть что-бы число обновлялось каждый раз при изменении количества записей в датасете). Как это лучше сделать?
Аватара пользователя
Unvictis
новенький
 
Сообщения: 48
Зарегистрирован: 17.07.2015 18:59:12
Откуда: Kokshetau, Kazakshtan

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение velaskes » 10.04.2016 21:36:15

Unvictis, попробуйте разработку без DB компонентов. TListView и минимум для подключения к БД. Все процессы станут 100% контролируемыми и прозрачными. Я уже давно к такому подходу перешел, нервные клетки то... они как известно не восстанавливаются :D
velaskes
новенький
 
Сообщения: 24
Зарегистрирован: 11.03.2016 23:16:17

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение Unvictis » 10.04.2016 21:47:47

Unvictis писал(а):попробуйте разработку без DB компонентов.

Благодарю, я таким образом писал дипломный проект.. Но по-моему, это не самый оптимальный подход. Рассуждая так можно и до ассемблера скатиться, - там вообще всё прозрачно. Шутка конечно, но такой подход лишает Lazarus (и ведь отчасти именно поэтому Delphi "прижилась" у наших разработчиков) скорости разработки приложений для баз данных, одной из самых сильных сторон этих IDE.
Аватара пользователя
Unvictis
новенький
 
Сообщения: 48
Зарегистрирован: 17.07.2015 18:59:12
Откуда: Kokshetau, Kazakshtan

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение velaskes » 10.04.2016 21:51:47

Unvictis писал(а):это не самый оптимальный подход

Так и есть, а еще код получается достаточно громоздким. Но зато это самый гибкий подход.
velaskes
новенький
 
Сообщения: 24
Зарегистрирован: 11.03.2016 23:16:17

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение pupsik » 11.04.2016 02:41:56

В общем, решил проблему так: с событии AfterPost...
т.е. мой вариант не сработал?
Что весьма печально (почти). В лине на свс версиях фпс и лазаря работает как положено.
RefetchData можно и не использовать. Тогда будут дополнительные "прелести".
Да и что делает св-во компонента SaveonRefetch ?

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

п.с.
Почитав http://wiki.freepascal.org/TSqlite3_Master_Detail_Example и http://wiki.freepascal.org/MasterDetail появляется скользкий момент:
Adding detail records with the right foreign key
Although detail records scroll with master records, additional code is needed.
When adding new detail records, the SALES.CUST_NO field is still NULL unless we fill it. So we need to set up an AfterInsert event handler for qrySales:
.
И напрашивается вывод: а всё ли так прекрасно и не проще ли стандартным набором пользоваться?
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение McLion » 11.04.2016 13:22:44

Не удивлюсь если TDBLookupComboBox глючит, такое в лазарусе часто встречается.
Аватара пользователя
McLion
постоялец
 
Сообщения: 332
Зарегистрирован: 06.02.2015 18:41:00

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение alexs » 11.04.2016 16:15:34

McLion писал(а):Не удивлюсь если TDBLookupComboBox глючит, такое в лазарусе часто встречается.


100% не верно работает рефреш после post.
Либо PK не находится, либо ещё что.

Вот это поведение - это симптомы именно этого:
Unvictis писал(а):с событии AfterPost компонентов SQLite3Dataset которые привязаны к Lookup-полям просто закрывал, а потом открывал его методами Close и Open (при этом свойство SaveOnClose = True).


PS
А не использовать DB компоненты - лишний геморой. Они работают правильно. Надо только быть аккуратным при написании запросов и работе с транзакциями.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: TDBLookupComboBox: Странное поведение (не обновляется)

Сообщение pupsik » 11.04.2016 18:29:45

аккуратным при написании запросов и работе с транзакциями
к чему транзакции и запросы... Вопрошающий делает всё это через сторонний компонент (почти сторонний). Похож на ADOTable из дельфина. Т.е. все запросы и нюансы в фоне.

TDBLookupComboBox глючит
в данном варианте по ссылкам выше. Есть нюанс работы с ключевыми полями. по ссылке и написано решение (вот интересно: кто то читал? :)). Это вместо:
просто закрывал, а потом открывал его методами Close и Open
.

п.с.
Свое время глядел этот компонент. Простота - это не залог здоровья нервных клеток.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 225

Рейтинг@Mail.ru
cron