Форум: "Базы";
Текущий архив: 2002.10.17;
Скачать: [xml.tar.bz2];
ВнизФильтрация с подчиненными таблицами Найти похожие ветки
← →
Юра (2002-09-04 18:37) [0]Локальная база, Paradox, TTable.
Есть таблица, в ней графа "Производитель". Для каждой записи в этой графе может быть от одного до двух десятков производителей. И для многих записей эти производители одинаковы. Соответственно, я породил подчиненную таблицу, в которой лежат ссылки на таблицу просмотра с производителями. Т.е. в главной таблице в поле "Производитель" стоит, предположим, 10. В подчиненной таблице по соотношению master-detail выбираются все записи, у которых поле связи равно 10. Второе поле в подчиненной таблице - уникальный идентификатор записи в таблице просмотра, где и лежат названия производителей, которые подставляются в LookUp поле подчиненной таблицы. Для реализации контекстной фильтрации в подчиненной таблице просматриваются все записи, пока они не кончатся или пока не будет найдена первая, удовлетворяющая условию. Т.е. функцией Pos в поле LookUp ищется заданная подстрока, и если она есть - запись в главной таблице прошла фильтрацию.
Все работает хорошо до тех пор, пока не начинается фильтрация основной таблицы по полю "Производитель" (фильтрация идет в обработчике OnFilterRecord). Во-первых, отключается связь master-detail, но это можно еще как-то пережить. Самое же ужасное - мерцание данных на экране. Disablecontrols тут не поможет - OnFilterRecord вызывается часто.
Я вижу два пути, как это побороть:
1. Неправильная организация данных, но как сделать лучше, избежав избыточности - не вижу.
2. Ввести в главную таблицу булевское поле и при фильтрации по производителю делать DisableControls для всех таблиц, пробегать все записи в главной таблице, занося в булевское поле результат фильтрации по производителю, а потом в обработчике OnFilterRecord смотреть значение булевского поля.
Есть еще какой-то выход?
← →
Shaman_Naydak (2002-09-04 19:26) [1]Что-то я начал читать и совсем заморочился..
Тебе нужно реализовать обычную связку многие ко многим.
Пример:
Таблица 1 - Виды продукции
ProductID - ключ
ProductName - название
Таблица 2 - Производители
ManufacturerID - ключ
ManufacturerName - название
добавляем табличку
Таблица 3 - Связка Вида продукции с производителями
Содержит 2 поля:
ProductID - foreign на табличку 1
ManufacturerID - foreign на табличку 2
И все!
1. Табличку 3 делаешь Detail по отношению к табличке 1
2. В FieldsEditor"e добавляешь Lookup поле, ссылающееся на табличку 2...
Наслаждаешься результатом и никакой фильтрации!
← →
Юра (2002-09-05 12:56) [2]Ты коротко и ясно описал то, что написал я длинно. Все так и реализовано. Далее - пользователь хочет профильтровать первую таблицу, оставив все записи, в которых в названии производителя встречается сочетание "вский". Я это реализую в обработчике события OnFilterRecord Таблицы1. Как только Таблица1 переходит в состоние filtered=true, связь мастер-детаил рвется. Далее, при просмотре записей в Таблице3 естественно меняются данные в контроле (у меня это DBStringGrid+DBEdit). Tаблица2.DisableControls не поможет, т.к. обработчик OnFilterRecord вызывается очень часто. И как мне побороть разрыв связки мастер-детаил и мерцание контрола?
← →
Shaman_Naydak (2002-09-05 15:26) [3]Что-то я так и не понял почему у тебя связка рвется-то?
Но вот пара советов
Во-первых, если тебе нужно воспользоваться Таблицей3 как справочником, то нужно вытащить еще один датасет - таблицу4 и работать с ним, либо через Clone создать копию курсора Таблицы3. (опять таки, если я тебя правильно понял)..
Во-вторых, поставь на форме Query и в нем отработай запрос по требуемому тебе критерию фильтрации, результатом работы Query должно быть одно поля - ProductID из Таблички 1 моего примера.
В событии на OnFilterRecord проверяй, что есть в Query запись с таким ProductID..
В-третьих, советую все таки пересмотреть архитектуру программы и с использования TTable перейти на TQuery и клиент-сервер (что не означает, впрочем, использование запросов типа SELECT * FROM Table1 :) )
← →
Юра (2002-09-05 16:34) [4]Хм. Связка рвется, потому что как только для Таблицы1 ставится условие filtered=true выполняется метод Таблица1.DisableControls. А DisableControls не только отключает таблицу от контролов, но еще и разрывает связь мастер-детаил. Об этом написано в хелпе буквально одной строчкой, ну и на практике я это проверил :-)
Как со справочником работать не нужно, Таблица3 - служебная, она хранит только ссылки.
Относительно запроса я не совсем понял. Пусть мне нужно отфильтровать Таблицу1 так, чтобы в ней отобразились все препараты, в названии производителя которых встречается слово "завод". И что дальше? К чему привязывать Query (т.е. к какой парадоксовской таблице, к той же, к которой привязана Таблица1)?
Относительно перехода - TQuery мне субъективно не нравится. В локальной базе я от него большой пользы не вижу, хотя возможно что и не прав.
← →
Shaman_Naydak (2002-09-05 17:54) [5]Аа.. DisableControls я выпустил из виду :)
Ну см. для табличек по примеру в Query должен быть такой запрос
SELECT DISTINCT ProductID FROM Таблица3
WHERE ManufacturerID IN (SELECT ManufacurertID FROM Таблица2
WHERE ManufactName LIKE "%завод%")
И, должен заметить, что если есть желание заниматься БД серьезно, то выхода у вас нет :)
в On FilterRecord у Table1 надо написать:
Accept:=Query.Locate("ProductID", Table1.FieldByName("ProductID").Value, []);
Вот, пишу по памяти, возможны ошибки
← →
VAleksey (2002-09-05 18:08) [6]Я вподобной ситуации так и сделал.
> Shaman_Naydak © (05.09.02 17:54)
Не очень красиво, но работает.
← →
Юра (2002-09-24 16:56) [7]Вот странно - по отдельности все работает, а вместе - нет!
Запрос в Query обрабатывается - я подцепил к нему DBStringGrid и посмотрел. Но вот на этом операторе:
Accept:=Query.Locate("ProductID", Table1.FieldByName("ProductID").Value, []);
буквально на первом десятке записей возникает ошибка. Причем вот что странно, если сделать так:
Query.Locate("ProductID", Table1.FieldByName("ProductID").Value, []);
Accept:=true (или Accept:=false, не важно)
то все работает!
Где может быть зарыта собака?
← →
MsGuns (2002-09-24 18:20) [8]Если это из складского учета, то по всей вероятности, корень проблем лежит в неверном построении самой картотеки. Картотека должно строиться в 2 этажа (не считая обычных LookUp - справочников):
1. (Master) Таблица товаров (изделий, продукции и т.д.)
TovarID - Primary Key идентификитор (ключ) товара
TovarKol - Актуальное кол-во на складе
... - все сопутствующие реквизиты
TovarDataIn - Дата последнего прихода
TovarDataOut - Дата последнего расхода
TovarLastPst - Код (идент-р) последнего поставщика (произ-ля)
TovarLastPok - Код (идент-р) последнего покупателя (заказчика)
2. (Detail) Таблица движения
TovarID - Primary Key идентификитор товара (LINK KEY)
DokDate - Primary Key Дата прихода-расхода
DokType - Primary Key Тип движения (П-приход,Р-расход)
DokNumb - Primary Key Номер прихода-расхода
DokKol - Кол-во по док-ту ("+"-для прихода, "-"-для расхода)
DokSumU - Сумма учетная
DokSumR - Сумма отгрузки (только для расходов)
DokPst - Код поставщика (производителя)
DokPok - Код покупателя (заказчика)
... - сопутствующие (наценка, вх/вых НДС и т.д.)
При обработке первички (приходно-расходные) документы можно использовать для фактуры клиентский ds. При добавлении-изменении-удалении каждой строки первички (фактуры накладной) обработчики
AfterPost/Delete автоматически вносят коррекции в движении, а при постировании записи в таблицы движения срабатывает триггер, который пересчитывает соотв.итоговые значения по данной позиции товара и записывают их в Master. Т.о. в самой картотеке по каждой карточке имеется "свежие" кол-во, сумма, последние поставщик/покупатель
Поиск и фильтр для одной позиции (карточки) - обычные по полям
таблицы движения
Поиск (фильтрация) по заданному (заданным) производителям (покупателям) выполняется запросом то ли по указанному, то ли по последнему поставщику/покупателю с выборкой или всех товаров, где поставщик "отметился", или толькл тех, где этот поставщик был последним (это чаще всего требуется менеджерам)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.10.17;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.008 c