Access - Помогите новичку
Есть таблица с полями "код" и "название". В форме показываю только поле "название".
Как мне узнать какое значение поля "код" для текущей записи. У меня уже крыша поехала.
p.s. если обобщить: есть значение val. Надо в конкретной таблице Tab отыскать запись, где в поле pole1 значение равно val и вытащить значение другого поля pole2.
Разбираюсь с Access. Возникла проблема.
Есть таблица с полями "код" и "название". В форме показываю только поле "название".
Как мне узнать какое значение поля "код" для текущей записи. У меня уже крыша поехала.
p.s. если обобщить: есть значение val. Надо в конкретной таблице Tab отыскать запись, где в поле pole1 значение равно val и вытащить значение другого поля pole2.
SELECT <Имя поля> FROM <ИМЯ ТАБЛИЦЫ> WHERE <ИМЯ ПОЛЯ, в котором условие> = <значение, которое должно в нём быть>
В твоём случае
SELECT pole2 FROM Tab WHERE pole1=val
Мне все это надо записать в коде VBA.
Private Sub AAA()
Dim rst As Recordset
Dim tdf As TableDef
Dim dbs As Database
Set dbs = CurrentDb
Set tdf = dbs.TableDefs("ИМЯ ТАБЛИЦЫ")
???????????
<ПЕРЕМЕННАЯ> = ?????????
End Sub
А можно поподробнее, пожалуйста!
Мне все это надо записать в коде VBA.
Private Sub AAA()
Dim rst As Recordset
Dim tdf As TableDef
Dim dbs As Database
Set dbs = CurrentDb
Set tdf = dbs.TableDefs("ИМЯ ТАБЛИЦЫ")
???????????
<ПЕРЕМЕННАЯ> = ?????????
End Sub
Не помню. какую библиотеку Access использует по умолчанию. но запрос будет примерно такой:
Dim rst As Recordset
Dim tdf As TableDef
Dim dbs As Database
Set dbs = CurrentDb
Set tdf = dbs.TableDefs("SELECT pole2 FROM Tab WHERE pole1=" & val)
Правда, давно этим не занимался, пишу на скорую руку и может не работать. Но общий смысл такой.
Не помню. какую библиотеку Access использует по умолчанию. но запрос будет примерно такой:
Dim rst As Recordset
Dim tdf As TableDef
Dim dbs As Database
Set dbs = CurrentDb
Set tdf = dbs.TableDefs("SELECT pole2 FROM Tab WHERE pole1=" & val)
Правда, давно этим не занимался, пишу на скорую руку и может не работать. Но общий смысл такой.
Я так понимаю, что найденая запись будет текущей.
А как переменной P1 присвоить значение поля pole2?
Я так понимаю, что найденая запись будет текущей.
А как переменной P1 присвоить значение поля pole2?
Val - значение, которому должно быть равно значение pole1. Тебе нужно изменить значение в pole2, дибо выбрать pole2 для которого pole1 = определённому значению?
Мне нужно узнать какое значение этого поля и по нему отсортировать другую базу.
I'm sorry:) . Обозналси
Private Sub AAA()
Dim rst As Recordset
Dim tdf As TableDef
Dim dbs As Database
Dim Otvet As Variant
DIM StrSQL as string
Set dbs = CurrentDb
Set tdf = dbs.TableDefs("ИМЯ ТАБЛИЦЫ")
StrSql = "("SELECT pole2 FROM Tab WHERE pole1=" & val"
Set Rst= dbs.OpenRecordset(StrSql)
If Not Rst.eof AND Not Rst.bof THen
Otvet = Rst!Fields(0) '(как вариант Rst.Fields (0) - в зависимости от используемой библиотеки - я сейчас этот синтаксис точно не помню, а искать некогда)
endif
End Sub
Завтра попробую. Если не получится тогда, попрошу еще раз помочь.
Спасибо!!!!
Завтра попробую. Если не получится тогда, попрошу еще раз помочь.
Всегда пожалуста!:)
на форму размещается Поле связанное с полем таблицы - "код", только оно делается скрытым - .Visible=False
1. теперь в любой момент обращаемся к скрытому полю программно и спокойно получаем необходимо нам значение, которое 100% соответствует текущей записи.
Если вы думаете, что это не профессионально, то вы глубоко заблуждаетесь, это весьма распространенная уловка.
В принципе все это было бы конечно все равно, если бы не один нехороший момент в самих рассуждениях автора вопроса, который не лучшим образом определил постановку задачи. Именно поле "код" обычно в таблице является уникальным и неповторимым и поэтому именно по нему делают выборку и нахождения конкретной записи. В случае же поиска по полю "название" мы можем получить несколько записей, которые имеют одинаковые названия. Хорошо конечно если таких нет, но при наличии поля "код" обычно именно оно отвечает за уникальность и для однозначного нахождения записи лучше использовать именно его.
С данной проблемой, я вроде бы разобралась. Но не сочтите за труд, дайте несколько советов.
1. Что лучше использовать "Запрос" или делать выборку и сортировку в форме?
2. Если в базе данных много таблиц и к некоторым обращение не такое частое, то можно их поместить в другой файл mdb и обращать к ним по мере надобности, открывая этот файл (или лучше все хранить в одном файле)?
3. Что лучше: хранить много много данных в одной таблице и выбирать определенный набор по коду или лучше для каждого набора создавать свою таблицу? (порядок записей таков: несколько сотен в каждом наборе и таких наборов то же где-то несколько сотен)
Буду очень признательна, если поможете советом, а то книг у меня много, но конкретного ( по моим вопросам) ничего пока найти не могу.
Заранее благодарна!
Как хорошо, что вы мне ответили. Я смотрю, вы во многом разбираетесь.
С данной проблемой, я вроде бы разобралась. Но не сочтите за труд, дайте несколько советов.
1. Что лучше использовать "Запрос" или делать выборку и сортировку в форме?
2. Если в базе данных много таблиц и к некоторым обращение не такое частое, то можно их поместить в другой файл mdb и обращать к ним по мере надобности, открывая этот файл (или лучше все хранить в одном файле)?
3. Что лучше: хранить много много данных в одной таблице и выбирать определенный набор по коду или лучше для каждого набора создавать свою таблицу? (порядок записей таков: несколько сотен в каждом наборе и таких наборов то же где-то несколько сотен)
Буду очень признательна, если поможете советом, а то книг у меня много, но конкретного ( по моим вопросам) ничего пока найти не могу.
Заранее благодарна!
Это-чисто моё личное мнение, но, по-моему
1. Удобнее делать выборку и сортировку в форме (хотя я всегда делаю запросы). Просто часто форму приходится привязывать к хранимому запросу ("въюшке"), а не к таблице
2. Хранить данные в одной БД, либо нескольких - выбор пользователя. Не стоит забывать, что *.mdb файлы часто "рушатся", поэтому разделение часто помогает спасти часть данных, хотя и замедляет работу (по-моему, опять-таки). Однако, одним из принципов стабильности работы с БД является разделение данных и кода. Поэтому, если БД большая, вообще лучше весь пользовательский код, такой как коды форм, процедуры, модули, вынести в отдельные файлы. Правда, насколько я помню, в соответствии с этими же принципами рекомендуется выделять и запросы, что я, честно говоря, никогда не делал. Ну а если проект маленький, то не стоит вообще с этим заморачиваться.
3. По поводу 3 вопроса я не до конца понял. Принцип тут такой - если есть возможность структурировать данные и разнести их по разным таблицам, и это не приведёт к сущесьвенному усложнению БД (как правило, это должно вести даже к упрощению БД и уменьшению объёма данных, которые должны в ней храниться), то лучше данные разнести по разным таблицам. Классический пример, таблицы заказов и товаров. Можно и то, и другое хранить в одной таблице, а можно создать 2, или даже 3 таблицы (заказы, товары и связь между заказами и товарами).
Я в основном делаю выборку и сортировку еще в запросе. Это во много раз быстрей, а когда данных много, это весомый аргумент. Тем более это проще.
2. Если в базе данных много таблиц и к некоторым обращение не такое частое, то можно их поместить в другой файл mdb и обращать к ним по мере надобности, открывая этот файл (или лучше все хранить в одном файле)?
Я бы хранил все в одном файле. в противном случае придется коннектиться к той базе, проверять,существует ли такая и т.д.... тем более кто знает среднестатистического криворукого юзера, которому нужно будет что-та сделать с самим файлом БД...
Не рекомендуется создавать 2 и более таблиц, если эти же данные можно поместить в одну таблицу. Количество в 10000 записей Access даже и не заметит %)
Да незачто %))
Я в основном делаю выборку и сортировку еще в запросе. Это во много раз быстрей, а когда данных много, это весомый аргумент. Тем более это проще.
Я бы хранил все в одном файле. в противном случае придется коннектиться к той базе, проверять,существует ли такая и т.д.... тем более кто знает среднестатистического криворукого юзера, которому нужно будет что-та сделать с самим файлом БД...
Не рекомендуется создавать 2 и более таблиц, если эти же данные можно поместить в одну таблицу. Количество в 10000 записей Access даже и не заметит %)
Да незачто %))
Не рекомендуется создавать 2 и более таблиц, если эти же данные можно поместить в одну таблицу. Количество в 10000 записей Access даже и не заметит %)
А прикинь,какого потом работать с этой таблицей? И какова будет гибкость такой БД?
Как хорошо, что вы мне ответили. Я смотрю, вы во многом разбираетесь.
С данной проблемой, я вроде бы разобралась. Но не сочтите за труд, дайте несколько советов.
1. Что лучше использовать "Запрос" или делать выборку и сортировку в форме?
Запрос с условием работает в несколько раз быстрее, чем загрузка ВСЕХ данных в форме и их последующая фильтрация. НО, если предполагается что пользователь будет интенсивно работать с форммой, задавая разные условия фильтрации, тоды конечно лучше чуток подождать с зугрузкой всех записей в форму, зато потом будешь быстро менять условия фильтрации и получать результат.
2. Если в базе данных много таблиц и к некоторым обращение не такое частое, то можно их поместить в другой файл mdb и обращать к ним по мере надобности, открывая этот файл (или лучше все хранить в одном файле)?
Тут тебе все уже ответили...
3. Что лучше: хранить много много данных в одной таблице и выбирать определенный набор по коду или лучше для каждого набора создавать свою таблицу? (порядок записей таков: несколько сотен в каждом наборе и таких наборов то же где-то несколько сотен)
Вероятно речь идет о типичной ситуации с нормализацией таблиц. Щас объясню:
Если ты например собираешься сделать базу типа дневника и хранить каждый день, а в дополнении к данным по каждому дню тебе еще важно знать к какой неделе он относится.
Тут соответсвенно два варианта проектирования базы:
1. пихаем все в одну таблицу, называем ее - день, в ней храним поля: Дата, Примечание, "Распорядок дня" и "Номер недели". Соответственно когда надо будет отображать дни по неделям, то приходится делать фильтрацию по полю - "Номер недели".
2. Однако есть второй путь, более практичный. Разбить эту таблицу на две (это как раз и называется нормализацией). Ты создаешь таблицу "Неделя" и таблицу "День" и связываешь их связью - "один ко многим", ставишь при этом условия каскадного обновления и соблюдения целостности данных.
Преймущества:
1. Данные логично разбиты на две таблицы. Т.е. все что касается дня хранится в таблице - день, все что касается недели хранится в таблице - неделя. Все структурно разбито и никакой путаницы. Кроме того теперь можно хранить данные относящие к самой неделе.
2. Достигается гибкость в дальнейшем структурном проектировании. Если в будущем понадобиться добавить поля с информацией о самой неделе, это можно легко сделать не трогая структуру таблицы - день.
3. Данные храняться в единственном варианте. Если у тебя 5 недель, то будет всего 5 записей с кодами недель, а первом варианте код недели будет дублироваться столько раз, сколько у тебя записей в таблице - день. Т.е. достигается экономия места и ресурсов, что для любой базы является немаловажным фактором.
4. И наконец, со связанными таблицами (с проставленными условиями: каскадного обновления и соблюдения целостности данных) сама база будет следить за обновлением информации и не даст тебе вбить для новой записи дня несуществующий номер недели и наоборот, ты можешь спокойно удалить запись неделя и вместе с ней каскадно удаляться связанные записи из таблицы - день.
P.S. да, и не надо думать, что выборка из большой таблицы с условием WHERE будет быстрее, чем выборка из связанных таблиц. Как раз наоборот, выборка по связи уже изначально с оптимизирована и происходит быстрее.
У меня по поводу третьего вопроса не все понятно.
Вот пример: есть ДОКУМЕНТ и у него есть СПИСОК ОБОРУДОВАНИЯ.
Я знаю что надо сделать таблицу ДОКУМЕНТЫ (там храняться все документы) и таблицу ОБОРУДОВАНИЯ, в которой будет поле КОД для ссылки к таблице ДОКУМЕНТЫ.
Вопрос в следующем. Может быть лучше будет если для каждой записи таблицы ДОКУМЕНТЫ будет своя таблица в которой будет находится список оборудования для этой записи. Т.е. у меня будет ссылка не на общую базу ОБОРУДОВАНИЯ, в котрой я буду выбирать записи с определенным кодом, а конкретная таблица. Ведь в таком случае мне не надо будет харнить поле КОД, а имена таблицам присваивать Const+Kod.
Кстати, а сколько таблиц всего может быть в файле MDB? Есть ли какие-то ограничения?
Спасибо всем за советы.
У меня по поводу третьего вопроса не все понятно.
Вот пример: есть ДОКУМЕНТ и у него есть СПИСОК ОБОРУДОВАНИЯ.
Я знаю что надо сделать таблицу ДОКУМЕНТЫ (там храняться все документы) и таблицу ОБОРУДОВАНИЯ, в которой будет поле КОД для ссылки к таблице ДОКУМЕНТЫ.
Вопрос в следующем. Может быть лучше будет если для каждой записи таблицы ДОКУМЕНТЫ будет своя таблица в которой будет находится список оборудования для этой записи. Т.е. у меня будет ссылка не на общую базу ОБОРУДОВАНИЯ, в котрой я буду выбирать записи с определенным кодом, а конкретная таблица. Ведь в таком случае мне не надо будет харнить поле КОД, а имена таблицам присваивать Const+Kod.
Кстати, а сколько таблиц всего может быть в файле MDB? Есть ли какие-то ограничения?
По-моему, для каждого оборудования делать отдельную таблицу - это слишком.
Спасибо всем за советы.
У меня по поводу третьего вопроса не все понятно.
Вот пример: есть ДОКУМЕНТ и у него есть СПИСОК ОБОРУДОВАНИЯ.
Я знаю что надо сделать таблицу ДОКУМЕНТЫ (там храняться все документы) и таблицу ОБОРУДОВАНИЯ, в которой будет поле КОД для ссылки к таблице ДОКУМЕНТЫ.
Вопрос в следующем. Может быть лучше будет если для каждой записи таблицы ДОКУМЕНТЫ будет своя таблица в которой будет находится список оборудования для этой записи. Т.е. у меня будет ссылка не на общую базу ОБОРУДОВАНИЯ, в котрой я буду выбирать записи с определенным кодом, а конкретная таблица. Ведь в таком случае мне не надо будет харнить поле КОД, а имена таблицам присваивать Const+Kod.
Кстати, а сколько таблиц всего может быть в файле MDB? Есть ли какие-то ограничения?
Вот как раз так делать и нельзя. У тебя данные по оборудованию будут дублироваться в сотне таблицах - это вопиющее нарушение основного правила проектирования базы данных по разделению данных и минимизации хранимой информации. Вообще, на будущее, основной принцип очень простой,надо стремиться уменьшать размеры хранимой информации (не хранить одинаковую, продублированную;размер полей выбирать по минимуму), а также не хранить информацию, которая может быть вычислена из исходных данных (исключения, только если очень долгие вычисления, для убыстрения последующих вычислений, можно конечно заранее вычислять и хранить промежуточные значения - главное только четко отдавать себе отчет, для чего это делается).
В твоем случае проблема решается очень просто, описанный выше вариант 2:
Создаем 3 таблицы: "Документ", "Список оборудования", "Оборудование".
Примерная структура таблиц(с их полями) и связи между ними такая (ща попробую изобразить):
"Документ": "Список обор.":
(к)КодДокумента------>КодДокумента
Название (к)Код
и т.д. КодОборудования <----
"Оборудование":
--- (к)КодОборудования
2 Название
Цена
и т.д.
Обозначения:
(к) - ключевое поле
---> - связь между таблицами "один ко многим", стрелка как раз указывает какие поля из таблиц необходимо связать. Там где начало стрелки "---" это один, а где конец "->" это "ко многим"
Все.
Теперь таблица с описанием оборудования храниться в единственном экземпляре, коды ее оборудования подставляются вдругие таблицы, где занимают гораздо меньше места, чем полная запись про оборудование. Таблица "Список обор." служит соединительным звеном где храниться соответствие между кодом документа и кодом оборудования. В дальнейшем с такой структурой горазда легче работать составляя запросы на выборку и т.д.
!!"Документ": !!!!!! "Список обор.":
(к)КодДокумента------>КодДокумента
Название!!!!!!!!!!!!!!(к)Код
и т.д. !!!!!!!!!!!!!!!КодОборудования <----
!!!!!"Оборудование":
----(к)КодОборудования
!!!!!Название
!!!!!Цена
!!!!!и т.д.
Я опять не так сформулировала.
Начну сначала.
Есть таблицы: ОБОРУДОВАНИЕ, ДОКУМЕНТЫ, СПИСОК ОБОРУДОВАНИЯ_ДЛЯ_КАЖДОГО_ДОКУМЕНТА
В последней таблице само собой храняться <код документа><код оборудования>
Я-то вот что хочу:
- что бы были таблицы ОБОРУДОВАНИЕ, ДОКУМЕНТЫ, ОБОРУДОВАНИЕ_ДОКУМЕНТА_1, ... , ОБОРУДОВАНИЕ_ДОКУМЕНТА_N
(т.е. таблицу ОБОРУДОВАНИЯ_ДЛЯ_КАЖДОГО_ДОКУМЕНТА
разбить на N таблиц по числу документов. Тогда в этих таблицах не будет поля <код документа>, а только поле <код оборудование> и в таблице ДОКУМЕНТЫ появится поле <ИМЯ ТАБЛИЦЫ>)
Хорошо ли это?
(причем N ~ 500 и в каждой такой таблице ~ 300 записей)
И сколько может быть таблиц в одном файле (примерный порядок)?
p.s. Вы уж извините меня за неправильную формулировку.
Надеюсь, здесь все должно быть понятно.
Есть таблицы: ОБОРУДОВАНИЕ, ДОКУМЕНТЫ, СПИСОК ОБОРУДОВАНИЯ_ДЛЯ_КАЖДОГО_ДОКУМЕНТА
В последней таблице само собой храняться <код документа><код оборудования>
Я-то вот что хочу:
- что бы были таблицы ОБОРУДОВАНИЕ, ДОКУМЕНТЫ, ОБОРУДОВАНИЕ_ДОКУМЕНТА_1, ... , ОБОРУДОВАНИЕ_ДОКУМЕНТА_N
(т.е. таблицу ОБОРУДОВАНИЯ_ДЛЯ_КАЖДОГО_ДОКУМЕНТА
разбить на N таблиц по числу документов. Тогда в этих таблицах не будет поля <код документа>, а только поле <код оборудование> и в таблице ДОКУМЕНТЫ появится поле <ИМЯ ТАБЛИЦЫ>)
Хорошо ли это?
(причем N ~ 500 и в каждой такой таблице ~ 300 записей)
Это не меняет дела - одно поле в одной таблице (всего на 4 байта!) куда гуманнее, чем 500 таблиц без этого поля. Вы абсолютно ничего не получаете, даже размер БД, поскольку описание структуры, ключей и т.д. таблицы занимает вовсе не 5 и не 10 байт. Тем более КУДА сложнее работать с 500-ми таблицами, чем с одной! Да по тем-же именам. Прийдется в таблице хранить строковое значение названия таблицы, а это совсем никуда не годится!
Все ясно.
Но ,в принципе, все понятно (пока!). Так что спасибо за советы.
А надо мне все это, что бы программульку одну написать (не по своей конечно воли).
Но ,в принципе, все понятно (пока!). Так что спасибо за советы.
Все мы невольны, только некоторые из нас работают на себя (например я %)))). Если что - обращайтесь!
Почему, во многих источниках, я вижу такой код
Private Sub aaaa()
Dim rst As Recordset
Set rst = Me.RecordsetClone
rst.Findfirst ...
......
End Sub
или что-то подобное и работает ведь.. Но у меня постоянно вылезает ошибка в строке SEt rst=..... и не находит Findfirst. А вот в таком варианте - все нормально
Private Sub aaaa()
Dim rst As DAO.Recordset
Set rst = Me.RecordsetClone
rst.Findfirst ...
......
End Sub
Что за ерунда? И вообще, какая разница между Recordset и DAO.Recordset в данном контексте?
Так вот, в каждой из этой библиотеки есть объект Recordset и поэтому когды ты пишешь: Dim a as Recordset, то коммпилятор пробегает по иерархии объектов и ищет в какой же библиотеки этот объект находится. В случае с Recordset он натыкается на первую же библиотеку, это может быть DAO или ADO, все зависит от того, какая из них выше стоит в списке подключенный библиотек (меню Tools/References). Естественно что в разных библотеках у Recordset немного разные свойства и методы.
Поэтому хорошим тоном считается соблюдать явное объявление переменной с полным путем до библиотеки. Dim a as DAO.Recordset Кроме того, если ты не используешь библиотеку ADO, то можно ее просто отключить из ссылок.
Но когда я пишу DAO все работает,
а когда ADODB - получаю ошибку на строку
SET rst=Me.RecordsetClone (Type Mismatch)
Почему? Ведь RecordsetClone там то же есть.
И как тогда надо записать. Наверное ему не нравиться Me.
Заранее благодарю.
p.s. если нетрудно, напишите как называется та умная книжечка, которую вы упомянули.
У меня подключены обе библиотеки.
Но когда я пишу DAO все работает,
а когда ADODB - получаю ошибку на строку
SET rst=Me.RecordsetClone (Type Mismatch)
Почему? Ведь RecordsetClone там то же есть.
И как тогда надо записать. Наверное ему не нравиться Me.
Заранее благодарю.
p.s. если нетрудно, напишите как называется та умная книжечка, которую вы упомянули.
Нет, просто в твоем случае происходит наложение с еще одной особенностью, вот цитата из Гетца:
Свойство формы RecordsetClone возвращает объект Recordset того же типа, что и исходный: в MDB-файле это объект DAO, а в ADP-файле - объект ADO
Книга: Пол Литвин, Кен Гетц, Майк Гунделой. Разработка настольных приложений в Access 2002. Для профессионалов(+CD) - СПб.: Питер; К:Издательская группа ИРМб 2002 - 1008 с.
ISBN 5-94723-499-8
Книга: Пол Литвин, Кен Гетц, Майк Гунделой. Разработка настольных приложений в Access 2002. Для профессионалов(+CD) - СПб.: Питер; К:Издательская группа BHV, 2002 - 1008 с.
ISBN 5-94723-499-8