|
|
|
Rodeon |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Здравствуйте.
Не каждая контора может позволить себе систему электронного документооборота и контроля исполнения поручений, поэтому для своего удобства делаю небольшую прогу по отслеживанию приказов, распоряжений и т.д. Ситуация следующая: база данных на MySQL В первой таблице хранятся тэги, которые подгружаются в CheckListBox, где выбираются (как например: 2016, подписанные, актуальные, 2015 и т.д.) Во второй таблице собственно перечень приказов с полями (дата, название, ссылка на диске на сам приказ и т.д.) Одно из полей (текстовое) включает в себя так называемые теги, т.е. перечень слов через запятую, которые добавляются выбором из CheckListBox при добавления нового приказа (одна запись может содержать несколько тегов). Для поиска нужного документа, выбираю необходимые теги из CheckListBox, запрос формирую подобным образом:
В принципе все работает, выбирали теги или нет и вполне все устраивает. Вопрос в следующем, может есть более лаконичный путь, чтобы потом переделывать не пришлось? Как в целом реализовать вывод информации из базы, содержащей теги или реализовать поиск данных по ключевым словам? В шапке опечатка, поздно заметил. Это сообщение отредактировал(а) Rodeon - 7.12.2016, 02:06 |
|||
|
||||
Garmahis |
|
|||
Опытный Профиль Группа: Участник Сообщений: 254 Регистрация: 23.12.2004 Репутация: нет Всего: 4 |
Правильнее сделать третью таблицу для связи тегов с документами. В таблице достаточно 2 полей: IDDocument и IDTeg. При таком подходе будет гораздо проще делать выборку по тегам.
|
|||
|
||||
Rodeon |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Хм... немного не могу понять как оно будет работать?!
У меня и так отдельная таблица с тэгами, в ней всего 1 поле - Char, в каждую строку занесен один тэг. При выводе приказов все поля подгружаются в sCheckListBox, и путем выбора нужных тегов в списке остаются необходимые приказы. Т.е. выбрал например тэги: "2016", "назначения", "ТБ" выведет все приказы (другая таблица), у которых в строке Tags (длиной 250) встречаются все вышеуказанные слова. Правильно ли я вас понял, для каждого документа свои тэги будут или как? не пойму предложенной вами реализации. |
|||
|
||||
Vas |
|
|||
Опытный Профиль Группа: Участник Сообщений: 828 Регистрация: 29.6.2005 Где: Stavropol region Репутация: 23 Всего: 28 |
Документы
ИД Название Теги Ид Название Таблица для связи многие ко многим ИД_Документа Ид_Тега -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
Rodeon |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Дошло наконец, что вы хотели сказать.
Все сделал, проверил, запрос заботает в таком виде:
Только это полдела, так как он выводить все приказы, в которых есть хотя бы 1 тег. У меня в таблице: каждому документу присваивается несколько тегов: ИД_Документа Ид_Тега 1 1 1 2 1 6 2 1 2 6 2 4 и т.д. Осталось разобраться как сюда прикруть выборку тегов, т.е. выводить только те приказы, которые выбраны в sCheckListBox. Может не через sCheckListBox, но хотелось бы визуализировать выбор. Добавлено @ 12:05 Все, так вобще хорошо: в конце добавляет ID тегов, и выводит только те приказы у которых они есть:
Таким образом избавился от цикла, все делается в 1 запрос. Всем спасибо. Это сообщение отредактировал(а) Rodeon - 8.12.2016, 12:07 |
||||
|
|||||
Vas |
|
|||
Опытный Профиль Группа: Участник Сообщений: 828 Регистрация: 29.6.2005 Где: Stavropol region Репутация: 23 Всего: 28 |
Все верно! Это сообщение отредактировал(а) Vas - 8.12.2016, 13:27 -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
Rodeon |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
В виду того, что не нашел бесплатный компонент DbCheckListBox, пришлось по списку выбранных в sCheckListBox-е пунктов пробегать циклом.
Ну и чтобы галочку поставить, что вопрос решенный. Это сообщение отредактировал(а) Rodeon - 9.12.2016, 01:17 |
|||
|
||||
Garmahis |
|
||||
Опытный Профиль Группа: Участник Сообщений: 254 Регистрация: 23.12.2004 Репутация: нет Всего: 4 |
Правильнее работать через Object.
Грузить в sCheckListBox1 записи в цикле по таблице тегов селектишь id и teg и пихаешь вот так:
Соотвественно id тегов получаешь примерно так:
|
||||
|
|||||
mailworker6 |
|
|||
Unregistered |
http://tuvaonline.ru/banja_ydovolctvie_i_polza.dhtml
если вас интересует турецкая баня в Москве или хамам, то вам тем более нужно в «Таёжные бани», где вашему желанию непременно найдётся реализация. Интересной особенностью турецких бань всегда была было повышенное внимание к внутренней архитектуре и убранству, которое должно сразу настроить посетителя на то, что он вступает в храм, храм омовения и чистоты не только тела. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
mailworker6 |
|
|||
Unregistered |
http://tuvaonline.ru/banja_ydovolctvie_i_polza.dhtml
если вас интересует турецкая баня в Москве или хамам, то вам тем более нужно в «Таёжные бани», где вашему желанию непременно найдётся реализация. Интересной особенностью турецких бань всегда была было повышенное внимание к внутренней архитектуре и убранству, которое должно сразу настроить посетителя на то, что он вступает в храм, храм омовения и чистоты не только тела. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
mailworker6 |
|
|||
Unregistered |
http://tuvaonline.ru/banja_ydovolctvie_i_polza.dhtml
если вас интересует турецкая баня в Москве или хамам, то вам тем более нужно в «Таёжные бани», где вашему желанию непременно найдётся реализация. Интересной особенностью турецких бань всегда была было повышенное внимание к внутренней архитектуре и убранству, которое должно сразу настроить посетителя на то, что он вступает в храм, храм омовения и чистоты не только тела. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
mailworker6 |
|
|||
Unregistered |
http://tuvaonline.ru/banja_ydovolctvie_i_polza.dhtml
если вас интересует турецкая баня в Москве или хамам, то вам тем более нужно в «Таёжные бани», где вашему желанию непременно найдётся реализация. Интересной особенностью турецких бань всегда была было повышенное внимание к внутренней архитектуре и убранству, которое должно сразу настроить посетителя на то, что он вступает в храм, храм омовения и чистоты не только тела. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
mailworker6 |
|
|||
Unregistered |
http://tuvaonline.ru/banja_ydovolctvie_i_polza.dhtml
если вас интересует турецкая баня в Москве или хамам, то вам тем более нужно в «Таёжные бани», где вашему желанию непременно найдётся реализация. Интересной особенностью турецких бань всегда была было повышенное внимание к внутренней архитектуре и убранству, которое должно сразу настроить посетителя на то, что он вступает в храм, храм омовения и чистоты не только тела. Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
Rodeon |
|
||||||||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Огромное спасибо. Только попробовал предложенный вами код, все очень и очень стало проще. Теперь все подставляемые значения хранятся в 1 таблице, у каждого свой уникальный (!!!) ID. При заполнении разных Combobox-ов и CheckBox-ов просто игнорирую null строки. Конечный SQL запрос для вывода в общую базу только вырос. Чтобы наглядно было, мало ли кому понадобится (сделал маленькую базу на 3 колонки (ID, Type, Status):
В итоге, после выбора в sComboBox-ах нужных строк, индексы в таблице, соответствующие именно выбранным строковым значениям получаем следующим образом, как пример:
|
||||||||||
|
|||||||||||
Rodeon |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
В таблице "PRIKAZ" основной ключ ID, но у него нет автоинкремента.
Чтобы не делать функцию получения максимального значения ключа, добавляем в саму таблицу для поля/ключа ID триггер:
Т.е. в данном случае после создания новой записи в таблице, триггер автоматом создаст новый, уникальный ключ. Далее загружаю данные из дочернего окна PrikazForm:
Все работает, проверил. Может знатоки посоветуют где можно улучшить, как ранее советовал Garmahis!? |
||||
|
|||||
Vas |
|
|||
Опытный Профиль Группа: Участник Сообщений: 828 Регистрация: 29.6.2005 Где: Stavropol region Репутация: 23 Всего: 28 |
Зачем такие сложности? Чем автоинкрементное поле не угодило в MySQL? Это сообщение отредактировал(а) Vas - 12.12.2016, 11:38 -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
Rodeon |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Эм... тут такая штука. На самом деле база данных стала FireByrd, а в ней нет по умолчанию поля с автоинкрементом. Все потому, что я новичок в базах данных и только изучаю. Сперва была MySQL, но с момента создания темы перешел на FireByrd Embedded по ряду причин, основная это автономность. |
|||
|
||||
Vas |
|
|||
Опытный Профиль Группа: Участник Сообщений: 828 Регистрация: 29.6.2005 Где: Stavropol region Репутация: 23 Всего: 28 |
В таком случает триггер отличный вариант.
[off] Embedded умеет и мускуль Но капризный слегка [/off] Это сообщение отредактировал(а) Vas - 12.12.2016, 13:05 -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
Rodeon |
|
||||||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Да простят меня модераторы, буду описывать план действий дальнейшего создания приложения.
Сегодня реализуем Drag & Drop файла (-ов) приказа на форму программы, открытие окна для ввода данных по приказу и сохранения всех данных в базу. Изначально решил, что после добавления приказа, файлы (jpg, pdf) будут копироваться в определенную папку на жестком диске, рядом с программой. Но имя им будет присвоено на основе MD5 хеша (расширение сохраняем), тем самым убиваем сразу 3 зайцев: 1. удобно проверить если уже подобный файл добавлен (совпадут хеши). 2. более короткое имя файла становится автоматом (32 символа, вместо N-го которым у нас привыкли обзывают других отделы, от этого много косяков потом бывает). 3. При несанкционированном доступе к папке фиг найдешь что-то, так как все файлы будут иметь имя 32 символа. Собственно, таблица для хранения файлов приказов будет такой: Первичный ключ:
Сама таблицу:
Создаем генератор:
Создаем триггер автоинкремента:
В базе: ID - тут будет уникальный индекс. ID_PRIKAZ - индекс на ID приказа. SHORT_NAME - имя файла(32) + точка(1) и расширение (4) FULL_NAME - имя файла по факту (ограничение имени файла NTFS - 255 символов) Т.е. визуально для пользователя будет выводится FULL_NAME, фактически везде SHORT_NAME. |
||||||||
|
|||||||||
Rodeon |
|
||||||||||||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Обрабатываем взброса файлов на форму (исходники нашел на просторах интернета, самую малостью изменил под свои нужды):
Для события создания формы добавляем:
В Uses добавляем:
Добавил глобальный объект:
Создаем новый тип:
Для формы добавляем новую процедуру:
Добавляем функции, процедуры и т.д.:
Таким образом: Catcher.FileCount у нас хранится количество файлов. Catcher.Files[N] - имя файла номер N. Не забываем после окончания работ с полученным списком файлов уничтожить объект:
Это сообщение отредактировал(а) Rodeon - 12.12.2016, 14:56 |
||||||||||||||
|
|||||||||||||||
Rodeon |
|
||||||||||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Перепробовал несколько готовых модулей получения хеша, CRC32 короткое имя, самое то MD5, собственно сам модуль:
Добавляем в программу:
Собственно сам модуль:
Вызываем следующим образом (на выходе строка длиной 32 символа):
Добавлено через 7 минут и 20 секунд Для добавления в базу потребуются преобразования имени файла: Получить имя файла, без пути и расширения:
Получить расширение имени файла:
И все вместе, получаем имя файла преобразованное в MD5 + расширение:
|
||||||||||||
|
|||||||||||||
Rodeon |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Чтобы получить ID созданной записи в таблице PRIKAZ (для увязки файлов ID_PRIKAZ.FILE_PRIKAZ к приказу) необходимо обратится к генератору:
добавим переменную, в которую будем получать ID:
После создания записи в таблице PRIKAZ получаем ID этой записи:
Теперь у нас в переменной ID_return последний ID таблицы PRIKAZ. P.S. как оказалось в FireByrd-е мало того, что нету поля с автоинкрементом, так еще и нет метода подобному GetInsertID. |
||||
|
|||||
Rodeon |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Заполняем таблицу FILE_PRIKAZ (помним, что для поля ID.FILE_PRIKAZ ранее создан триггер-автоинкремент, в Catcher у нас хранятся файлы дропнутые на форму, в ID_return хранится ID.PRIKAZ только что созданного приказа):
Т.е., что мы сделали: в ID_PRIKAZ записали ID приказа. в SHORT_NAME записали MD5 от реального имени файла + расширение сохранили в FULL_NAME записали реальное имя файла, которое и будет участвовать в последующем в визуализации. Помимо этого скопировали все файлы в подпапку, где лежит сама программа с новыми именами MD5 с сохранением расширения. |
|||
|
||||
Rodeon |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 28.8.2008 Где: Россия, Ухта Репутация: нет Всего: нет |
Для тегов у нас таблица:
Добавляем тэги с базу PRIKAZ_TAGS сопоставляя с индексом последнего приказа ID_return:
P.S. Да поправят меня знатоки: размер транзакции может быть до 16 мб, Commit желательно делать каждые 1000 изменений. |
||||
|
|||||
Правила форума "Delphi: Базы данных и репортинг" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами Обязательно указание: 1. Базы данных (Paradox, Oracle и т.п.) 2. Способа доступа (ADO, BDE и т.д.)
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |