'моя таблица будет синдексом Name по полю Name
Dim DB As Database, RST As Recordset, tbl As TableDef, ndx As Index, Fld As Field
Set DB = DBEngine.OpenDatabase("c:\555\", True, False, "DBASE IV;")
Set tbl = DB.TableDefs("registr")
Set ndx = New Index
ndx.Name = "name"
Set Fld = ndx.CreateField("name")
Call ndx.Fields.Append(Fld)
Call tbl.Indexes.Append(ndx)
Что такое индексы?
Set db = DBEngine.OpenDatabase("c:\555\", True, False, "DBASE IV;")
Set rst = db.OpenRecordset("registr.dbf", dbOpenTable)
rst.movenext
db.close
Базы данных большие и поск необходимой записи выполняю перебором всех записей и сравнением и проверка длится до 2-3-5 часов. А один парень сказал надо делать индексы и работать через индексы.
Если кто знает как создавать индексные файлы для баз данных формата dbase, а самое главное как обращаться к записям в индексных файлах подскажите пожалуйста.
Очень надо помочь
1. Подключаешь базу ты через Set rst = db.OpenRecordset, а как ты поиск делаешь? ведь у ADODB.Recodset (да и у DAO.Recordset) есть свои родные методы поиска по recodset'у типа .Find, .Seek
2. Потом с базами, у тебя каждый день разные dbf файлы или все-таки они не так часто меняются? это важно, потому что индексы создаются непосредственно в самой базе данных применительно к какой-то таблице по каким-то определенным полям. Причем на создание индекса тратится время. Т.е. предполагается что ты указываешь какие поля будут индексированы, база данных их индексирует (это занмает время), а потом ты используешь эту таблицы делая по ней поиск и за счет индексов он идет быстрее. Конечно при каждом изменение записей в таблице базе данных необходимо проделывать переиндексацию - но это уже плата за использование индексов(то бишь поиск индексы ускоряют, а добавление/именение замедляют), поэтому всегда нужно искать разумный компромисс.
Т.о. если база виа меняется не часто, возможно проще будет засунуть ее в Access и уже в нем проиндексировать часто используемые поля и обращаться уже к ней.
1. Поясняю я делаю цикл do while перед циклом я перехожу на первую запись rst.movelast, цикл выполняется пока небудет достигнут конец файла в цикле есть rst.movenext и теперь просто сравниваю.
rst.movelast
do while rst.eof=false
if rst.fields(0)="Воробьев" then
exit do
end if
rst.movenext
loop
2. База данных у меня не так часто обновляется мне дают все базу льготников которым можно выписывать льготные рецепты а я проверяю можно ли этому человеку выписывать льготный рецепт то есть есть ли он в базе или нет.
3. А вот через rst.find осуществлять поиск я пробывал но так и не смог правильно написать синтаксис, и помощь читал и примеры смотрел что то неберется при компиляции дает ошибку.
Если тебе нетрудно напиши как правильно надо осущестлять поиск через find там же надо показать из какого столбца базы данных брать и искать. Спасибо еще раз.
Цитата:
Originally posted by nice ..
как правильно надо осущестлять поиск через find там же надо показать из какого столбца базы данных брать и искать.
как правильно надо осущестлять поиск через find там же надо показать из какого столбца базы данных брать и искать.
Seek используется для рекордсетов табличного вида, при этом нужно чтобы был предварительно создан индекс
DAO 3.6
Код:
Тода поиск выглядит примерно так
Код:
Set RST = DB.OpenRecordset("registr.dbf", dbOpenTable)
With RST
.Index = "NAME"
.Seek "=", "Iam" 'Iam - искомое значение
Debug.Print .Fields("NAME").Value
End With
With RST
.Index = "NAME"
.Seek "=", "Iam" 'Iam - искомое значение
Debug.Print .Fields("NAME").Value
End With
Если без индексов и нетабличного типа рекордсет, то можно использовать
Код:
With rst
.FindFirst "name='Iam'"
end with
With rst
.FindFirst "name='Iam'"
end with
With rst
Однако, если есть возможность, то выбирать лучше всего через SELECT с ограничениями WHERE, соответственно рекордсет открывать через
Код:
DB.OpenRecordset("SELECT * FROM registr WHERE Name='Iam'")
Тогда выборка будет содержать только необходимые данные и только их нужно перебирать через .MoveNext
Цитата:
Originally posted by blind rain
Однако, если есть возможность, то выбирать лучше всего через SELECT с ограничениями WHERE, соответственно рекордсет открывать через
Тогда выборка будет содержать только необходимые данные и только их нужно перебирать через .MoveNext
Однако, если есть возможность, то выбирать лучше всего через SELECT с ограничениями WHERE, соответственно рекордсет открывать через
Код:
DB.OpenRecordset("SELECT * FROM registr WHERE Name='Iam'")
Тогда выборка будет содержать только необходимые данные и только их нужно перебирать через .MoveNext
Попробывал
With rst
.FindFirst "FAM='Воробьев'"
end with
With rst
искать по полю FAM фамилию Воробьев. И ничего нехочет иска а ругается и пишит "Операция не поддерживается".
Попробывал
DB.OpenRecordset("SELECT * FROM registr WHERE Fam='Воробьев'")
Ни начто не ругается и не ищет. А мог бы ты мне подсказать по подробней что каждое слово означает ("select"искать, "from"где, "registr",база, where, поле)
я думаю что это означает так. Но поиск не происходит. А что когда он найдет то переведет курсор на текущию запись.
2. По синтаксису SQL можно помощь по Access посмотреть, а лучше книжку какую-нибудь почитать.
3. Я незнаю, чем писалось в таблицу, но вполне возможно, в поле данные содержат пробелы после значимой части слова. Поэтому можно попробовать использовать функцию TRIM()
Код:
DB.OpenRecordset("SELECT * FROM registr WHERE Trim(Name)='Iam'")
4. Рекордсет - не есть таблица. Рекордсет - это выборка записей. Поэтому при создании рекордсета через SELECT, он будет содержать ТОЛЬКО подходящие под условие записи.
P.S. Есть множество статей по использованию SQL, поэтому очень рекомендую их почитать - жизнь существенно упростится.
Я работаю с DAO 3.6 и может раскажете как осущестлять поиск через ..FindFirst
Ещё есть seek но как с ним работать я тоже никак не смог.
Цитата:
Originally posted by nice
Вроде сделал программа компилируется нет никаких ошибок но и результата я невижу. Он что должен переходить на найденную запись или что должно произойти.
Вроде сделал программа компилируется нет никаких ошибок но и результата я невижу. Он что должен переходить на найденную запись или что должно произойти.
Код:
Dim rst As DAO.recordset, Myvalue As String
Set rst = DB.OpenRecordset("SELECT * FROM registr WHERE Trim(name)='Iam'")
Do while not rst.EOF
'записываем результат из каждой записи
'соответствующей нашему условию в переменную
'и потом выводим в Immediate экран в режиме отладки
'естественно, если Вы выбирали Select *, в
'каждой записи доступны значения всех полей
'таблицы, эти значения Вы можете считать и
'использовать как угодно в своих расчетах
MyValue = rst.Fields("Name").Value & ""
Debug.print MyValue
rst.Movenext()
loop
Set rst = DB.OpenRecordset("SELECT * FROM registr WHERE Trim(name)='Iam'")
Do while not rst.EOF
'записываем результат из каждой записи
'соответствующей нашему условию в переменную
'и потом выводим в Immediate экран в режиме отладки
'естественно, если Вы выбирали Select *, в
'каждой записи доступны значения всех полей
'таблицы, эти значения Вы можете считать и
'использовать как угодно в своих расчетах
MyValue = rst.Fields("Name").Value & ""
Debug.print MyValue
rst.Movenext()
loop
Попробуйте в режиме отладки посмотреть, выполняется ли условие =.EOF
При использовании .FindFirst и Seek в случае успеха должен перейти на найденную запись.
P.S.
Я уже давно не пользовался DAO, а от использования
перебора или поиска через FindFirst изначально отказался по причинам производительности. Seek работает только при наличия индекса по полю.
Если имеется возможность, выложите свой код поиска, и маленкую вырезку базы (хотя бы 4 записи), я посмотрю в чем проблема.