У меня есть база данных туристов, состоящая из двух свя...

Автор ForumOOo (бот), 26 июля 2013, 13:20

0 Пользователи и 1 гость просматривают эту тему.

JohnSUN

Да, знакомая ситуация... Я, когда с туризмом впервые столкнулся, тоже не знал, как правильно вопросы задавать - все вокруг всё знают и понимают, а я не вижу разницы между туроператором и турагентом, партнером и принимающей стороной...
Ты не стесняйся, спрашивай прямо как получится. Даже если мы не сразу поймем, о чем вопрос - просто переспросим.
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Лариса

Выкладываю свою базу, как она у меня получилась
Какие у меня вопросы:
1.   Как сделать отчеты с такой информацией:
Отчет 1: Заезд. Группа. Выезд. Убытие. Стоимость тура. Оплачено
Отчет 2: Группа. ФИО участников группы. Паспортные данные (все), прописка
Отчет 3: ФИО, дата рождения, дата заезда.
2.   Как то у нет у меня связи между группой и туристами... Поэтому запрос получается с дублирующимися данными.
3.   Как сделать, чтобы в отчетах отображались только нужные данные, ну например заезд в определенную дату, а не вся база?


[вложение удалено Администратором]

JohnSUN

Лариса, если я сейчас покажусь скучным и занудным - не обращай внимания: конец не самой лёгкой недели, притомился слегка.

Поехали!
Сначала совсем слегка покритикую структуру базы - вообще-то, всё сделала более-менее толково, но придраться есть к чему.
Для подсчета денег ты используешь целочисленное поле (Integer). Имеешь право, конечно - кто сейчас эти копейки считает? Но "идеологически" это не правильно. Если вдруг расчет пойдет не в рублях, а сразу в нескольких валютах, то отсутствие возможности учёта копеек-центов-пенни может привести к существенным огрехам при пересчете курсов. Поэтому лучше для денег всегда использовать типы данных, в которых эти самые копейки можно задать и сохранить. Другое дело, что в экранных формах и отчетах можно подавить вывод этих "копеек", но в таблицах лучше хранить с ними.
Две таблицы Прибытие и Убытие - хорошее решение. Но тоже не совсем правильное. Если я верно понял смысл занесенных данных, то это номер рейса и время прилёта-вылета? В те же таблицы попали и фирменный "Лотос", и питерский поезд... А таблица "транспорт" к этим данным никаким боком не привязана. И получается, что ответственность за правильность внесения данных лежит на операторе, а не на программе. А кто мешает выбрать транспорт "авто" с прибытием "005Г - 06:10" и убытием "1175 - 19:00"? И зачем нужны эти справочники, если в таблицу Группы пишутся значения из них "живьем", в виде текста?
Если все делать "на таблицах", то, пожалуй, правильнее было бы сделать одну таблицу "Рейсы" с полями
Id(Integer)-Номер(Текст)-Время(Time)-ЭтоПрибытие(Логическое - или "сюда", или "отсюда")-ВидТранспорта(Integer - ссылка на запись в таблице "транспорт")
Тогда в таблице Группы вместо трех текстовых полей транспорт-прибытие-убытие можно было бы оставить два целочисленных поля-ссылки на записи этой таблицы (прибытие-убытие вносим выбирая из справочника, а вид транспорта "подтягивается" оттуда же как дополнительная информация).
Но это при условии, что вся группа прибывает и убывает синхронно и одним рейсом... Точно не бывает так, что кто-то приехал на поезде, а часть группы - на своей машине? Может быть есть смысл перенести эти поля в таблицу Id?
То же самое - хранение значения в текстовом виде, а не в виде ссылки на запись в справочнике - относится и к турагентству. Ну, вот представь ситуацию, что через какое-то время менеджер АстТрэвэл попросит во всех бумагах, которыми вы с ними обмениваетесь, называть их «AST-travel». И что тогда делать? Менять по всем таблицам, где они упоминались, одно название на другое? Проще один раз в таблице Турагенство изменить одно значение и оно тут же изменится везде, где надо. Да и база при этом займет меньше места - Integer по-любому меньше по размеру, чем VARCHAR(20).
Когда увидел, что связь Групп и Туристов сделана через кросс-таблицу Id, а в форме Группы используешь связь напрямую, кажется, наконец-то понял, о чем ты пыталась спросить раньше - как занести данные в промежуточную таблицу.
Дело в том, что Мастер создания форм предлагает сделать только двухуровневую форму. То есть главная форма, привязанная к одной таблице, и вложенная, подчиненная форма, привязанная к какой-то другой таблице. В большинстве случаев это достаточно.
То есть создавая таблицу Группы, нужно было просто в качестве главной таблицы указать Группы, а в качестве вложенной не Туристы, а Id. Потом, когда форма уже создана, можно изменить отображение "ID туриста" в виде целого числа, на его настоящие Имя-Фамилию, добавить дополнительные подчиненные формы со своими источниками данных и т.п.
Но сейчас, увы, ни об этом, ни об отчетах написать, наверное, не успею - опять зовут на помощь.
Об отчетах буквально в двух словах, насчет "Как сделать, чтобы в отчетах отображались только нужные данные..., а не вся база". Нужно изменить запрос на "запрос с параметром". Например, добавить в Запрос_Группы условие
...WHERE "Группы"."ID группы" = :НомерГруппы...
Тогда при запуске отчета Base смотрел бы, что для отчета требуется выполнить вот этот запрос, начинал бы его выполнять и обнаруживал бы, что нужно спросить у оператора дополнительные данные. И спрашивал бы (см. картинку)


[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Лариса

С каждым ответом у меня все больше вопросов! 
"Нужно изменить запрос на "запрос с параметром". Например, добавить в Запрос_Группы условие!" ... Как это сделать???
Простите мне мою тупость...

JohnSUN

Отставить панику! Ты - не тупая. Просто пока не очень много знаешь про новую для тебя область... Всё будет хорошо - мы все здесь не родились знатоками. Потерпи, скоро станет легче!

Цитата: Лариса от  9 августа 2013, 16:48
Как это сделать???
Лучше один раз увидеть... См. картинки.
В строчке Критерий в нужной колонке просто вписываем одно слово, которое начинается с двоеточия. Это и будет параметр.

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Лариса

Все, я поняла как делать запрос с условием! Спасибо! Только как это отразится на отчете? Или нужно каждый раз, как меняется запрос, делать отчет?

JohnSUN

В отчет попадут только те туристы, которые вошли в указанную группу...
Открываешь отчет - выскакивает вопрос, мол, для какой группы формировать... Пишешь "Бат" и получаешь туристов только из этой группы. Открываешь отчет еще раз - опять выскакивает вопрос, пишешь "Сол" - получаешь туристов из другой группы...
И тут, кстати, возникает еще проблемка. Ну, сейчас мы ведь сколько угодно групп можем обозвать "Бат" или "Сол". И значит все туристы из всех одноименных групп будут отбираться запросом. Нужно как-то заставить базу следить за уникальностью названия группы. Проще всего задать для поля группа отдельный индекс и указать, что он уникальный. Это в конструкторе таблицы нужно нажать кнопку "Проектирование индекса" на панели инструментов.
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Лариса

С отчетами я разобралась, спасибо! Но у меня получается многократное дублирование данный туристов из одной группы во все остальные группы. Это видно из примера в Запросе. Нет разнесения туристов по группам, принадлежности к одной фамилии главного в группе.

JohnSUN

Да-да, я начал было про это писать в пятницу, но вынужден был прерваться, отвлекли...
Та связь "многие-ко-многим", которую нужно было сделать с помощью промежуточной кросс-таблицы (у меня она называлась СоставГрупппы, у тебя ID), ты не смогла сразу правильно реализовать в форме Группы. Моя вина. Hasim прав, нужно было сразу подробно расписать как и что там нужно сделать.

За счет этой кросс-таблицы можно сделать как минимум две полезных формы. Одна - это группа (со всеми её параметрами - даты и способы заезда-выезда, старший группы, егерь, СТОИМОСТЬ - не оплата, а именно ОЖИДАЕМАЯ оплата!, и прочее) и привязанный к ней список туристов этой группы. А вторая - Турист и привязанные к нему все группы, в которых он уже отдыхал.
Сразу попытаюсь объяснить, почему настаиваю на внесении в данные группы не реально поступивших платежей, а только сумму выставляемого счета. Платеж может прийти частями. И в случае крупной суммы так чаще всего и будет. Вносить рассроченный платеж в одну и ту же ячейку Оплачено - значит сразу обречь себя на возможность технических ошибок (рука дрогнула и и какая-то цифирька не так вписалась) и на отсутствие истории платежей, в какие дни какие суммы по этой конкретной группе поступали. А эти сведения крайне важны для любой отчетности! Поэтому поступление средств тоже обычно оформляют отдельной табличкой (Id группы, дата поступления, сумма) и привязывают её к Группе связью "многие-к-одному". Некоторые перестраховщики так же поступают и со СтоимостьюТура, хотя меняется она гораздо реже, только при изменении количественного и возрастного состава группы, сроков заезда и условий проживания-питания. Но ведь может же меняться? Но об этом всём можно подумать и позже.

Итак, что неправильно с формой Группы? Подчиненная форма назначена не на ту таблицу.
Войди в редактирование этой формы (ПКМ - Изменить). Внизу формы панель инструментов "Дизайн формы". Эта панель включается кнопкой на панели инструментов "Элементы управления" или через меню Вид-Панели инструментов-Дизайн формы.
Сейчас нам нужны пятая и четвертая кнопки этой панели - сначала пятая "Навигатор форм". Открой панель навигатора и сдвинь в сторону - сейчас откроем еще и свойства формы (четвертая кнопка), так чтобы она не заслонила навигатора - сдвинь его чуть в сторонку.

Итак, навигатор. Вряд ли ты стала переименовывать элементы, которые создал Мастер форм, поэтому главная форма у тебя всё ещё должна называться MainForm, а подчиненная SubForm. Выдели эту SubForm в навигаторе и смело жми четвертую кнопку, нам нужно увидеть свойства этой вложенной формы, особенно нас интересуют сведения на вкладке Данные. Видишь? Вложенная форма SubForm использует Таблицу (тип содержимого) с именем Туристы (содержимое). И это не соответствует нашим связям между данными. Здесь должна быть таблица ID! Но теперь мало изменить источник данных, нужно еще указать, каким образом каждая запись главной формы будет отбирать в субформу записи из таблицы ID. Для этого нужно правильно указать значения "Связь с главным полем" и "Связь с подчиненным полем". Щелкни на кнопку с многоточием напротив любого из них и откроется формочка "Связь полей", здесь можно выбрать нужные поля обеих таблиц. Нам нужны и там, и там "ID группы" (если ты их еще не переименовала, конечно).
Готово! Теперь к группе привязан не весь список туристов, а только те, кого будем указывать в ID, как членов группы.
Осталось всего ничего: настроить таблицу SubForm_Grid на отображение "нормальных" данных из таблицы Туристы вместо простых чисел "ID туриста" из таблицы Id.

Упс... Опять не успел дописать. Будь добра, поковыряй мой образец - может быть, сможешь понять суть без дополнительных рассусоливаний... А я должен окунуться в текучку, сорри
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Лариса

Цитата: JohnSUN от 12 августа 2013, 12:12Щелкни на кнопку с многоточием напротив любого из них и откроется формочка "Связь полей", здесь можно выбрать нужные поля обеих таблиц. Нам нужны и там, и там "ID группы" (если ты их еще не переименовала, конечно)

То есть в "Свойстве формы", на вкладке "Данные", в строке "Связь с главным полем" в табличке "Связь полей" в обеих колонках должны выбрать ID Группы? Аналогично в строке "Связь с подчиненным полем" тоже в обеих колонках выбрать ID группы? Что то мне подсказывает, что где то все таки должно быть ID Туристы...

JohnSUN

Цитата: Лариса от 12 августа 2013, 15:23
То есть в "Свойстве формы", на вкладке "Данные", в строке "Связь с главным полем" в табличке "Связь полей" в обеих колонках должны выбрать ID Группы? Аналогично в строке "Связь с подчиненным полем" тоже в обеих колонках выбрать ID группы?
Я так и знал, что эти две кнопки тебя тоже собьют с толку. "Тоже" - потому что и я на первых порах пытался устанавливать нужные связи для каждого из этих полей, жал и ту и другую кнопки. "Мы с тобой одной крови - ты и я!".
Каждая из них открывает одну и ту же (!) формочку для установления связей между таблицами. И зачем там две кнопки - трудно сказать.
А так-то, да - всё верно: нужно указать, что формы связываются между собой по условию "ID"."ID группы"="Группы"."ID группы".

Цитата: Лариса от 12 августа 2013, 15:23Что то мне подсказывает, что где то все таки должно быть ID Туристы...
Нет, Это "что-то" ошибается  ;D Отображать в таблице в субформе будем "ID Туристы", а связь именно по "ID группы"
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Лариса

Цитата: JohnSUN от 12 августа 2013, 12:12Осталось всего ничего: настроить таблицу SubForm_Grid на отображение "нормальных" данных из таблицы Туристы вместо простых чисел "ID туриста" из таблицы Id.
Вот до этого все сделала... Честно скажу, поковыряла Ваш образец, но ничего не поняла... Нужно ли мне удалять мою субформу, а вместо нее делать субформу таблицы ID? И как можно настроить таблицу SubForm_Grid на отображение "нормальных" данных из таблицы Туристы вместо простых чисел "ID туриста" из таблицы Id?

JohnSUN

Цитата: Лариса от 13 августа 2013, 11:53Честно скажу, поковыряла Ваш образец, но ничего не поняла...
Во-первых, мы знакомы уже не первый день, поэтому вместо "Ваш образец" можешь смело писать "твой образец" - отсутствие формальностей в общении облегчает понимание... А то ведь я и отругать толком человека не могу, который ко мне "на Вы" обращается.  ;D
А во-вторых, насчет "ничего не поняла". Да, это я погорячился, когда посоветовал ковырять и не сказал с какой стороны. Попробовал образец открыть и взглянуть на него свежим взглядом - тоже мало что увидел. Нужно рассказывать по пунктам, тыча пальцем в каждый нюанс... Ну, значит, дальше так и будем поступать.
Цитата: Лариса от 13 августа 2013, 11:53Нужно ли мне удалять мою субформу, а вместо нее делать субформу таблицы ID?
Это один из вариантов редактирования формы. Другой способ заключается в переназначении источников данных для уже существующих субформы и её таблицы. Просто "перепривязываешь" данные с таблицы Туристы на таблицу ID. Это в свойствах субформы, на закладке Данные, поле Содержимое - просто выбираешь нужную таблицу из выпадающего списка.
Цитата: Лариса от 13 августа 2013, 11:53И как можно настроить таблицу SubForm_Grid на отображение "нормальных" данных из таблицы Туристы вместо простых чисел "ID туриста" из таблицы Id?
О, это интересный момент! Тут фокус в чем: сама таблица не имеет Данных, это свойство каждой отдельной колонки в таблице.  Нужно щелкнуть по заголовку столбца ПКМ и в меню увидишь целую пачку возможностей для работы с ним. Вот тут можно вернуться к образцу. Открой свойства столбца Турист и обрати внимание на заголовок окна свойств. Видишь? "Свойства: Список" Не "Текстовое поле", а "Список"! Этот элемент управления в отличие от других умеет делать потрясающую вещь - использовать в своих данных не значение одного поля из одной записи какой-то таблицы, а целую мини-табличку с данными. Обычно эта мини-табличка - результат выполнения какого-то SQL-запроса. И обычно состоит из двух колонок. В поле отображается значение из первой колонки (на самом деле она считается нулевой), а связь идет по значению из второй колонки этой мини-таблицы (ну, если считать с нуля, то "первой"). Эти "нулевые-первые" могут кого угодно сбить с толку... Ну, еще раз посмотри на свойства "образцовых Туристов", два самых нижних значения в закладке Данные - запрос, который выдергивает из данных о туристах ФИО и код (обрати внимание - первым идет ФИО, оно и будет отображаться в поле таблицы), и номер связываемого поля 1 - то есть вторая колонка в результатах запроса, КодТуриста.
Как работает форма целиком?
Главная форма привязана данными к таблице Группы. То есть она может отобразить КАЖДУЮ из записей этой таблицы. Почему большими жирными буквами? Потому что новички считают, что форма отображает ВСЕ записи. Дело в том, что одна запись в таблице является текущей и форма отображает именно её данные. И именно КодГруппы из этой записи (ты его назвала "ID группы") сигналит субформе,  какими записями из её, субформы, таблицы нужно будет работать.
Субформа смотрит в свою таблицу (например, ID), смотрит на связь с главным полем, отбирает из своей таблицы данных те записи, у которых "ID группы" такой же, как и у текущей записи главной таблицы, и пытается их отобразить в колонке таблицы (слишком путано получается из-за того слово "таблица" обозначает то таблицу данных, то элемент управления - но, надеюсь, сможешь понять "кто кому доктор").
А колонка типа Список перед тем как отобразить значение, которое ей подсунула субформа из своих данных, полезет в мини-табличку, которая прописана в её свойствах, отыщет ФИО, который соответствует полученному "ID туриста" и нарисует на экране именно ФИО, а не номер.
(Извини, если сегодняшний кусок информации изложен не очень доступно - пишу, а мысли заняты текучкой...)
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

njuton89

Цитата: JohnSUN от  9 августа 2013, 16:12* Запрос с параметром в конструкторе.png (57.9 Кб, 790x587 - просмотрено 91 раз.)

* Тот же запрос в режиме SQL.png (40.72 Кб, 733x388 - просмотрено 65 раз.)

Добрый день. А есть ли возможность этот критерий брать например из выпадающего списка на форме, и после уже делать запрос в базу?

JohnSUN

Можно. Но не обязательно "после". Можно сразу же. Называется "подчинённая форма".
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне